diff --git a/.badgery.yaml b/.badgery.yaml new file mode 100644 index 00000000..99bcdc1c --- /dev/null +++ b/.badgery.yaml @@ -0,0 +1,72 @@ +default_branch: master +develop_branch: develop + +cards: + - group: Tests + type: gh_action + title: Code/package tests (GitHub) + file: test.yml + enabled: true + - group: Tests + type: gh_action + title: Tutorial tests (GitHub) + file: tutorial-tests.yml + enabled: true + + - group: Tests + type: gh_action + title: Package tests (PyPI) + file: pypi-test.yml + enabled: true + + - group: Code Quality + type: codefactor + title: Code quality (CodeFactor) + enabled: true + + - group: Code Quality + type: radon_mi + title: Maintainability index (radon) + report: reports/{branch}/maintainability-index.json + enabled: true + + - group: Code Quality + type: radon_cc + title: Cyclomatic complexity (radon) + report: reports/{branch}/cyclomatic-complexity.json + enabled: true + + - group: Size + type: radon_loc + title: Source/Logical lines of code (radon) + report: reports/{branch}/raw-metrics.json + enabled: true + + - group: Size + type: radon_ff + title: Functions/Files count (radon) + report: reports/{branch}/cyclomatic-complexity.json + enabled: true + + - group: Coverage + type: codecov + title: Unit test coverage (Codecov) + flag: unittests + enabled: true + + - group: Coverage + type: interrogate + title: Docstring coverage (interrogate) + report: reports/{branch}/coverage-docstring.txt + enabled: true + - group: Build & Release + type: gh_action + title: Publishing (PyPI) + workflow: pypi-publish.yml + enabled: true + + - group: Build & Release + type: gh_action + title: Docs build/deployment + workflow: docs.yml + enabled: true diff --git a/.codecov.yml b/.codecov.yml index 5cf1eedd..e17376e8 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,8 +1,8 @@ github_checks: - annotations: true + annotations: true comment: - layout: "reach, diff, flags, files" + layout: 'reach, diff, flags, files' behavior: default - require_changes: false # if true: only post the comment if coverage changes - require_base: no # [yes :: must have a base report to post] - require_head: yes # [yes :: must have a head report to post] \ No newline at end of file + require_changes: false # if true: only post the comment if coverage changes + require_base: no # [yes :: must have a base report to post] + require_head: yes # [yes :: must have a head report to post] diff --git a/.copier-answers.yml b/.copier-answers.yml index a3add030..335c340b 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,12 +1,20 @@ -# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY -_commit: 1b51781 -_src_path: gh:/EasyScience/EasyProjectTemplate -description: Core foundation of the EasyScience family of projects, providing the - building blocks for libraries and applications -max_python: '3.12' -min_python: '3.8' -orgname: EasyScience -packagename: easyscience -prettyname: Easyscience -projectname: EasyScience -year: 2024 +# WARNING: Do not edit this file manually. +# Any changes will be overwritten by Copier. +_commit: v0.10.0 +_src_path: gh:easyscience/templates +lib_docs_url: https://easyscience.github.io/core +lib_doi: 10.5281/zenodo.18163581 +lib_package_name: easyscience +lib_python_max: '3.13' +lib_python_min: '3.11' +lib_repo_name: core +project_contact_email: support@easyscience.org +project_copyright_years: 2021-2026 +project_extended_description: The foundation of the framework, providing reusable + building blocks for scientific libraries and applications aimed at making data + analysis easier +project_name: EasyScience +project_short_description: Core building blocks for EasyScience +project_shortcut: ES +project_type: lib +template_type: lib diff --git a/.github/actions/download-artifact/action.yml b/.github/actions/download-artifact/action.yml new file mode 100644 index 00000000..e4fd62f5 --- /dev/null +++ b/.github/actions/download-artifact/action.yml @@ -0,0 +1,50 @@ +name: 'Download artifact' +description: 'Generic wrapper for actions/download-artifact' +inputs: + name: + description: 'Name of the artifact to download' + required: true + + path: + description: 'Destination path' + required: false + default: '.' + + pattern: + description: 'Glob pattern to match artifact names (optional)' + required: false + default: '' + + merge-multiple: + description: 'Merge multiple artifacts into the same directory' + required: false + default: 'false' + + github-token: + description: 'GitHub token for cross-repo download (optional)' + required: false + default: '' + + repository: + description: 'owner/repo for cross-repo download (optional)' + required: false + default: '' + + run-id: + description: 'Workflow run ID for cross-run download (optional)' + required: false + default: '' + +runs: + using: 'composite' + steps: + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.name }} + path: ${{ inputs.path }} + pattern: ${{ inputs.pattern }} + merge-multiple: ${{ inputs.merge-multiple }} + github-token: ${{ inputs.github-token }} + repository: ${{ inputs.repository }} + run-id: ${{ inputs.run-id }} diff --git a/.github/actions/github-script/action.yml b/.github/actions/github-script/action.yml new file mode 100644 index 00000000..ab32da56 --- /dev/null +++ b/.github/actions/github-script/action.yml @@ -0,0 +1,19 @@ +name: 'GitHub Script' +description: 'Wrapper for actions/github-script' +inputs: + script: + description: 'JavaScript to run' + required: true + + github-token: + description: 'GitHub token (defaults to github.token)' + required: false + default: ${{ github.token }} + +runs: + using: 'composite' + steps: + - uses: actions/github-script@v8 + with: + script: ${{ inputs.script }} + github-token: ${{ inputs.github-token }} diff --git a/.github/actions/setup-easyscience-bot/action.yml b/.github/actions/setup-easyscience-bot/action.yml new file mode 100644 index 00000000..4b28eaf8 --- /dev/null +++ b/.github/actions/setup-easyscience-bot/action.yml @@ -0,0 +1,40 @@ +name: 'Setup EasyScience bot for pushing' +description: 'Create GitHub App token and configure git identity + origin remote' +inputs: + app-id: + description: 'GitHub App ID' + required: true + private-key: + description: 'GitHub App private key (PEM)' + required: true + repositories: + description: 'Additional repositories to grant access to (newline-separated)' + required: false + default: '' + +outputs: + token: + description: 'Installation access token' + value: ${{ steps.app-token.outputs.token }} + +runs: + using: 'composite' + steps: + - name: Create GitHub App installation token + id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ inputs.app-id }} + private-key: ${{ inputs.private-key }} + repositories: ${{ inputs.repositories }} + + - name: Configure git for pushing + shell: bash + run: | + git config user.name "easyscience[bot]" + git config user.email "${{ inputs.app-id }}+easyscience[bot]@users.noreply.github.com" + + - name: Configure origin remote to use the bot token + shell: bash + run: | + git remote set-url origin https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/${{ github.repository }}.git diff --git a/.github/actions/setup-pixi/action.yml b/.github/actions/setup-pixi/action.yml index 8c68f51e..167ee623 100644 --- a/.github/actions/setup-pixi/action.yml +++ b/.github/actions/setup-pixi/action.yml @@ -4,13 +4,21 @@ inputs: environments: description: 'Pixi environments to setup' required: false - default: 'dev' + default: 'default' activate-environment: description: 'Environment to activate' required: false - default: 'dev' + default: 'default' run-install: - description: 'Whether to run install' + description: 'Whether to run pixi install' + required: false + default: 'true' + locked: + description: 'Whether to run pixi install --locked' + required: false + default: 'false' + frozen: + description: 'Whether to run pixi install --frozen' required: false default: 'true' cache: @@ -25,10 +33,12 @@ inputs: runs: using: 'composite' steps: - - uses: prefix-dev/setup-pixi@v0.9.0 + - uses: prefix-dev/setup-pixi@v0.9.4 with: environments: ${{ inputs.environments }} activate-environment: ${{ inputs.activate-environment }} run-install: ${{ inputs.run-install }} + locked: ${{ inputs.locked }} + frozen: ${{ inputs.frozen }} cache: ${{ inputs.cache }} - post-cleanup: ${{ inputs.post-cleanup }} \ No newline at end of file + post-cleanup: ${{ inputs.post-cleanup }} diff --git a/.github/actions/upload-artifact/action.yml b/.github/actions/upload-artifact/action.yml new file mode 100644 index 00000000..825ac396 --- /dev/null +++ b/.github/actions/upload-artifact/action.yml @@ -0,0 +1,49 @@ +name: 'Upload artifact' +description: 'Generic wrapper for actions/upload-artifact' +inputs: + name: + description: 'Artifact name' + required: true + + path: + description: 'File(s)/dir(s)/glob(s) to upload (newline-separated)' + required: true + + include-hidden-files: + description: 'Include hidden files' + required: false + default: 'true' + + if-no-files-found: + description: 'warn | error | ignore' + required: false + default: 'error' + + compression-level: + description: '0-9 (0 = no compression)' + required: false + default: '0' + + retention-days: + description: 'Retention in days (optional)' + required: false + default: '' + + overwrite: + description: 'Overwrite an existing artifact with the same name' + required: false + default: 'false' + +runs: + using: 'composite' + steps: + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.name }} + path: ${{ inputs.path }} + include-hidden-files: ${{ inputs.include-hidden-files }} + if-no-files-found: ${{ inputs.if-no-files-found }} + compression-level: ${{ inputs.compression-level }} + retention-days: ${{ inputs.retention-days }} + overwrite: ${{ inputs.overwrite }} diff --git a/.github/actions/upload-codecov/action.yml b/.github/actions/upload-codecov/action.yml new file mode 100644 index 00000000..37d6298a --- /dev/null +++ b/.github/actions/upload-codecov/action.yml @@ -0,0 +1,42 @@ +name: 'Upload coverage to Codecov' +description: 'Generic wrapper for codecov/codecov-action@v5' + +inputs: + name: + description: 'Codecov upload name' + required: true + + flags: + description: 'Codecov flags' + required: false + default: '' + + files: + description: 'Coverage report files' + required: true + + fail_ci_if_error: + description: 'Fail CI if upload fails' + required: false + default: 'true' + + verbose: + description: 'Enable verbose output' + required: false + default: 'true' + + token: + description: 'Codecov token' + required: true + +runs: + using: composite + steps: + - uses: codecov/codecov-action@v5 + with: + name: ${{ inputs.name }} + flags: ${{ inputs.flags }} + files: ${{ inputs.files }} + fail_ci_if_error: ${{ inputs.fail_ci_if_error }} + verbose: ${{ inputs.verbose }} + token: ${{ inputs.token }} diff --git a/.github/configs/pages-deployment.json b/.github/configs/pages-deployment.json new file mode 100644 index 00000000..c0d3fbee --- /dev/null +++ b/.github/configs/pages-deployment.json @@ -0,0 +1,6 @@ +{ + "source": { + "branch": "gh-pages", + "path": "/" + } +} diff --git a/.github/configs/rulesets-develop.json b/.github/configs/rulesets-develop.json new file mode 100644 index 00000000..04489e52 --- /dev/null +++ b/.github/configs/rulesets-develop.json @@ -0,0 +1,37 @@ +{ + "name": "develop branch", + "target": "branch", + "enforcement": "active", + "conditions": { + "ref_name": { + "include": ["refs/heads/develop"], + "exclude": [] + } + }, + "bypass_actors": [ + { + "actor_id": 2476259, + "actor_type": "Integration", + "bypass_mode": "always" + } + ], + "rules": [ + { + "type": "non_fast_forward" + }, + { + "type": "deletion" + }, + { + "type": "pull_request", + "parameters": { + "allowed_merge_methods": ["squash"], + "dismiss_stale_reviews_on_push": false, + "require_code_owner_review": false, + "require_last_push_approval": false, + "required_approving_review_count": 0, + "required_review_thread_resolution": false + } + } + ] +} diff --git a/.github/configs/rulesets-gh-pages.json b/.github/configs/rulesets-gh-pages.json new file mode 100644 index 00000000..ebf38928 --- /dev/null +++ b/.github/configs/rulesets-gh-pages.json @@ -0,0 +1,19 @@ +{ + "name": "gh-pages branch", + "target": "branch", + "enforcement": "active", + "conditions": { + "ref_name": { + "include": ["refs/heads/gh-pages"], + "exclude": [] + } + }, + "rules": [ + { + "type": "non_fast_forward" + }, + { + "type": "deletion" + } + ] +} diff --git a/.github/configs/rulesets-master.json b/.github/configs/rulesets-master.json new file mode 100644 index 00000000..f658a5c6 --- /dev/null +++ b/.github/configs/rulesets-master.json @@ -0,0 +1,30 @@ +{ + "name": "master branch", + "target": "branch", + "enforcement": "active", + "conditions": { + "ref_name": { + "include": ["~DEFAULT_BRANCH"], + "exclude": [] + } + }, + "rules": [ + { + "type": "non_fast_forward" + }, + { + "type": "deletion" + }, + { + "type": "pull_request", + "parameters": { + "allowed_merge_methods": ["merge"], + "dismiss_stale_reviews_on_push": false, + "require_code_owner_review": false, + "require_last_push_approval": false, + "required_approving_review_count": 0, + "required_review_thread_resolution": false + } + } + ] +} diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml deleted file mode 100644 index a95ea8fc..00000000 --- a/.github/release-drafter.yml +++ /dev/null @@ -1,32 +0,0 @@ -# https://github.com/marketplace/actions/release-drafter -name-template: v$NEXT_PATCH_VERSION 🌈 -tag-template: v$NEXT_PATCH_VERSION -categories: -- title: 🚀 Features - labels: - - feature - - enhancement -- title: 🐛 Bug Fixes - labels: - - fix - - bugfix - - bug -- title: 🧰 Maintenance - labels: - - chore - - documentation -change-template: '- $TITLE @$AUTHOR (#$NUMBER)' -version-resolver: - major: - labels: - - major - minor: - labels: - - minor - patch: - labels: - - patch - default: patch -template: | - ## Changes - $CHANGES diff --git a/.github/scripts/backmerge-conflict-issue.js b/.github/scripts/backmerge-conflict-issue.js new file mode 100644 index 00000000..f6bd98b5 --- /dev/null +++ b/.github/scripts/backmerge-conflict-issue.js @@ -0,0 +1,69 @@ +module.exports = async ({ github, context, core }) => { + // Repo context + const owner = context.repo.owner + const repo = context.repo.repo + + // Link to the exact workflow run that detected the conflict + const runUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}` + + // We use a *stable title* so we can find/reuse the same "conflict tracker" issue + // instead of creating a new issue on every failed run. + const title = 'Backmerge conflict: master → develop' + + // Comment/issue body includes the run URL so maintainers can jump straight to logs. + const body = [ + 'Automatic backmerge failed due to merge conflicts.', + '', + `Workflow run: ${runUrl}`, + '', + 'Manual resolution required.', + ].join('\n') + + // Label applied to the tracker issue (assumed to already exist in the repo). + const label = '[bot] backmerge' + + // Search issues by title across *open and closed* issues. + // Why: if the conflict was resolved previously and the issue was closed, + // we prefer to reopen it and append a new comment instead of creating duplicates. + const q = `repo:${owner}/${repo} is:issue in:title "${title}"` + const search = await github.rest.search.issuesAndPullRequests({ + q, + per_page: 10, + }) + + // Pick the first exact-title match (search can return partial matches). + const existing = search.data.items.find((i) => i.title === title) + + if (existing) { + // If a tracker issue exists, reuse it: + // - reopen it if needed + // - add a comment with the new run URL + if (existing.state === 'closed') { + await github.rest.issues.update({ + owner, + repo, + issue_number: existing.number, + state: 'open', + }) + } + + await github.rest.issues.createComment({ + owner, + repo, + issue_number: existing.number, + body, + }) + + core.notice(`Conflict issue updated: #${existing.number}`) + return + } + + // No tracker issue exists yet -> create the first one. + await github.rest.issues.create({ + owner, + repo, + title, + body, + labels: [label], + }) +} diff --git a/.github/workflows/backmerge.yml b/.github/workflows/backmerge.yml new file mode 100644 index 00000000..47b3384a --- /dev/null +++ b/.github/workflows/backmerge.yml @@ -0,0 +1,109 @@ +# This workflow automatically merges `master` into `develop` whenever a +# new version release with a tag is published. It can also be triggered +# manually via workflow_dispatch for cases where an automatic backmerge +# is needed outside of the standard release process. +# If a merge conflict occurs, the workflow creates an issue to notify +# maintainers for manual resolution. + +name: Backmerge (master → develop) + +on: + release: + types: [published, prereleased] + workflow_dispatch: + +permissions: + contents: write + issues: write + +concurrency: + group: backmerge-master-into-develop + cancel-in-progress: false + +jobs: + backmerge: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout repository (for local actions) + uses: actions/checkout@v5 + + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + repositories: ${{ github.event.repository.name }} + + - name: Checkout repository (with bot token) + uses: actions/checkout@v5 + with: + fetch-depth: 0 + token: ${{ steps.bot.outputs.token }} + + - name: Configure git identity + run: | + git config user.name "easyscience[bot]" + git config user.email "${{ vars.EASYSCIENCE_APP_ID }}+easyscience[bot]@users.noreply.github.com" + + - name: Set merge message + run: | + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + MESSAGE="Backmerge: master into develop (manual) [skip ci]" + else + TAG="${{ github.event.release.tag_name }}" + MESSAGE="Backmerge: master (${TAG}) into develop [skip ci]" + fi + + echo "MESSAGE=$MESSAGE" >> "$GITHUB_ENV" + echo "message=$MESSAGE" >> "$GITHUB_OUTPUT" + echo "📝 Merge message: $MESSAGE" | tee -a "$GITHUB_STEP_SUMMARY" + + - name: Prepare branches + run: | + git fetch origin master develop + git checkout -B develop origin/develop + + - name: Check if develop is already up-to-date + id: up_to_date + run: | + if git merge-base --is-ancestor origin/master develop; then + echo "value=true" >> "$GITHUB_OUTPUT" + echo "ℹ️ Develop is already up-to-date with master" | tee -a "$GITHUB_STEP_SUMMARY" + else + echo "value=false" >> "$GITHUB_OUTPUT" + fi + + - name: Try merge master into develop + id: merge + if: steps.up_to_date.outputs.value == 'false' + continue-on-error: true + run: | + if ! git merge origin/master --no-ff -m "${MESSAGE}"; then + echo "conflict=true" >> "$GITHUB_OUTPUT" + echo "❌ Backmerge conflict detected." | tee -a "$GITHUB_STEP_SUMMARY" + git status --porcelain || true + exit 0 + fi + + echo "conflict=false" >> "$GITHUB_OUTPUT" + echo "✅ Merge commit created." | tee -a "$GITHUB_STEP_SUMMARY" + + - name: Push to develop (if merge succeeded) + if: + steps.up_to_date.outputs.value == 'false' && steps.merge.outputs.conflict == + 'false' + run: | + git push origin develop + echo "🚀 Backmerge successful: master → develop" | tee -a "$GITHUB_STEP_SUMMARY" + + - name: Create issue (if merge failed with conflicts) + if: steps.merge.outputs.conflict == 'true' + uses: ./.github/actions/github-script + with: + github-token: ${{ steps.bot.outputs.token }} + script: | + const run = require('./.github/scripts/backmerge-conflict-issue.js') + await run({ github, context, core }) diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml new file mode 100644 index 00000000..7305679b --- /dev/null +++ b/.github/workflows/cleanup.yml @@ -0,0 +1,84 @@ +# This workflow will delete old workflow runs based on the input +# parameters. +# https://github.com/Mattraks/delete-workflow-runs + +name: Old workflow runs cleanup + +on: + # Run monthly, at 00:00 on the 1st day of month. + schedule: + - cron: '0 0 1 * *' + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + inputs: + days: + description: 'Number of days.' + required: true + default: 30 + minimum_runs: + description: 'The minimum runs to keep for each workflow.' + required: true + default: 6 + delete_workflow_pattern: + description: + 'The name or filename of the workflow. if not set then it will target all + workflows.' + required: false + delete_workflow_by_state_pattern: + description: + 'Remove workflow by state: active, deleted, disabled_fork, + disabled_inactivity, disabled_manually' + required: true + default: 'All' + type: choice + options: + - 'All' + - active + - deleted + - disabled_inactivity + - disabled_manually + delete_run_by_conclusion_pattern: + description: + 'Remove workflow by conclusion: action_required, cancelled, failure, skipped, + success' + required: true + default: 'All' + type: choice + options: + - 'All' + - action_required + - cancelled + - failure + - skipped + - success + dry_run: + description: 'Only log actions, do not perform any delete operations (dry run).' + required: false + default: 'false' + type: choice + options: + - 'false' + - 'true' + +jobs: + del-runs: + runs-on: ubuntu-latest + + permissions: + actions: write + + steps: + - name: Delete workflow runs + uses: Mattraks/delete-workflow-runs@v2 + with: + token: ${{ github.token }} + repository: ${{ github.repository }} + retain_days: ${{ github.event.inputs.days }} + keep_minimum_runs: ${{ github.event.inputs.minimum_runs }} + delete_workflow_pattern: ${{ github.event.inputs.delete_workflow_pattern }} + delete_workflow_by_state_pattern: + ${{ github.event.inputs.delete_workflow_by_state_pattern }} + delete_run_by_conclusion_pattern: + ${{ github.event.inputs.delete_run_by_conclusion_pattern }} + dry_run: ${{ github.event.inputs.dry_run }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index bcd75a1a..00000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,68 +0,0 @@ -# This pipeline - -name: "CodeQL" - -on: - push: - branches: [ master, develop ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ master ] - schedule: - - cron: '0 16 * * 5' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - # Override automatic language detection by changing the below list - # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] - language: ['python'] - # Learn more... - # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection - - steps: - - name: Checkout repository - uses: actions/checkout@v5 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 - - # If this run was triggered by a pull request event, then checkout - # the head of the pull request instead of the merge commit. - - run: git checkout HEAD^2 - if: ${{ github.event_name == 'pull_request' }} - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v3 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 \ No newline at end of file diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 00000000..cd9ff1e0 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,94 @@ +name: Coverage checks + +on: + # Trigger the workflow on push + push: + # Do not run on version tags (those are handled by other workflows) + tags-ignore: ['v*'] + # Trigger the workflow on pull request + pull_request: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Need permissions to trigger the dashboard build workflow +permissions: + actions: write + contents: read + +# Allow only one concurrent workflow, skipping runs queued between the run +# in-progress and latest queued. And cancel in-progress runs. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +# Set the environment variables to be used in all jobs defined in this workflow +env: + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + +jobs: + # Job 1: Run docstring coverage + docstring-coverage: + runs-on: ubuntu-latest + + steps: + - name: Check-out repository + uses: actions/checkout@v5 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Run docstring coverage + run: pixi run docstring-coverage + + # Job 2: Run unit tests with coverage and upload to Codecov + unit-tests-coverage: + runs-on: ubuntu-latest + + steps: + - name: Check-out repository + uses: actions/checkout@v5 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Run unit tests with coverage + run: pixi run unit-tests-coverage --cov-report=xml:coverage-unit.xml + + - name: Upload unit tests coverage to Codecov + if: ${{ !cancelled() }} + uses: ./.github/actions/upload-codecov + with: + name: unit-tests-job + flags: unittests + files: ./coverage-unit.xml + token: ${{ secrets.CODECOV_TOKEN }} + + # Job 2: Run integration tests with coverage and upload to Codecov + integration-tests-coverage: + runs-on: ubuntu-latest + + steps: + - name: Check-out repository + uses: actions/checkout@v5 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Run integration tests with coverage + run: + pixi run integration-tests-coverage --cov-report=xml:coverage-integration.xml + + - name: Upload integration tests coverage to Codecov + if: ${{ !cancelled() }} + uses: ./.github/actions/upload-codecov + with: + name: integration-tests-job + flags: integration + files: ./coverage-integration.xml + token: ${{ secrets.CODECOV_TOKEN }} + + # Job 4: Build and publish dashboard (reusable workflow) + run-reusable-workflows: + needs: [docstring-coverage, unit-tests-coverage, integration-tests-coverage] # depend on the previous jobs + uses: ./.github/workflows/dashboard.yml + secrets: inherit diff --git a/.github/workflows/dashboard.yml b/.github/workflows/dashboard.yml new file mode 100644 index 00000000..5159f71b --- /dev/null +++ b/.github/workflows/dashboard.yml @@ -0,0 +1,104 @@ +name: Dashboard build and publish + +on: + workflow_dispatch: + workflow_call: + +permissions: + contents: read + +# Set the environment variables to be used in all jobs defined in this workflow +env: + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + DEVELOP_BRANCH: develop + REPO_OWNER: ${{ github.repository_owner }} + REPO_NAME: ${{ github.event.repository.name }} + +jobs: + dashboard: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Install badgery + shell: bash + run: pixi add --pypi --git https://github.com/enhantica/badgery badgery + + - name: Run docstring coverage and code complexity/maintainability checks + run: | + for BRANCH in $DEFAULT_BRANCH $DEVELOP_BRANCH $CI_BRANCH; do + echo + echo "🔹🔸🔹🔸🔹 Processing branch $BRANCH 🔹🔸🔹🔸🔹" + if [ -d "../$BRANCH" ]; then + echo "Branch $BRANCH already processed, skipping" + continue + fi + + git worktree add ../$BRANCH origin/$BRANCH + mkdir -p reports/$BRANCH + + echo "Docstring coverage for branch $BRANCH" + pixi run interrogate -c pyproject.toml --fail-under=0 ../$BRANCH/src > reports/$BRANCH/coverage-docstring.txt + + echo "Cyclomatic complexity for branch $BRANCH" + pixi run radon cc -s -j ../$BRANCH/src > reports/$BRANCH/cyclomatic-complexity.json + + echo "Maintainability index for branch $BRANCH" + pixi run radon mi -j ../$BRANCH/src > reports/$BRANCH/maintainability-index.json + + echo "Raw metrics for branch $BRANCH" + pixi run radon raw -s -j ../$BRANCH/src > reports/$BRANCH/raw-metrics.json + done + + - name: Generate dashboard HTML + run: > + pixi run python -m badgery --config .badgery.yaml --repo ${{ github.repository + }} --branch ${{ env.CI_BRANCH }} --output index.html + + - name: Prepare publish directory + run: | + mkdir -p _dashboard_publish/${{ env.REPO_NAME }}/${{ env.CI_BRANCH }} + cp index.html _dashboard_publish/${{ env.REPO_NAME }}/${{ env.CI_BRANCH }} + + # Create GitHub App token for pushing to external dashboard repo. + # The 'repositories' parameter is required to grant access to repos + # other than the one where the workflow is running. + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + repositories: | + ${{ github.event.repository.name }} + dashboard + + # Publish to external dashboard repository with retry logic. + # Retry is needed to handle transient GitHub API/authentication issues + # that occasionally cause 403 errors when multiple workflows push concurrently. + # Uses personal_token (not github_token) as GITHUB_TOKEN cannot access external repos. + - name: Publish to main branch of ${{ github.repository }} + uses: Wandalen/wretry.action@v3.8.0 + with: + attempt_limit: 3 + attempt_delay: 15000 # 15 seconds between retries + action: peaceiris/actions-gh-pages@v4 + with: | + publish_dir: ./_dashboard_publish + keep_files: true + external_repository: ${{ env.REPO_OWNER }}/dashboard + publish_branch: master + personal_token: ${{ steps.bot.outputs.token }} + + - name: Add dashboard link to summary + run: | + URL="https://${{ env.REPO_OWNER }}.github.io/dashboard/${{ env.REPO_NAME }}/${{ env.CI_BRANCH }}" + echo "Dashboard link: [$URL]($URL)" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..c23c2c8c --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,184 @@ +# This workflow builds and deploys documentation for the project. +# +# Overview: +# - Converts tutorial Python scripts to Jupyter notebooks and executes them. +# - Builds the documentation site using MkDocs with the Material theme. +# - Uploads the built site as an artifact for local inspection. +# - Deploys versioned documentation to the gh-pages branch using Mike: +# - For release tags (v*): deploys to a versioned folder (e.g., /0.9.1/) and updates /latest/. +# - For branches: deploys to /dev/. +# +# The action summary page will contain a link to the built artifact for downloading +# and inspecting, as well as a link to the deployed documentation site. + +name: Docs build and deployment + +on: + # Trigger the workflow on push + push: + # Selected branches + branches: [develop] # master and main are already verified in PR + # Runs on creating a new tag starting with 'v', e.g. 'v1.0.3' + tags: ['v*'] + # Trigger the workflow on pull request + pull_request: + # Selected branches + branches: [master, main, develop] + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Allow only one concurrent deployment to gh-pages at a time. +# All docs workflows share the same concurrency group to prevent race conditions +# when multiple branches/tags trigger simultaneous deployments. +concurrency: + group: docs-gh-pages-deploy + cancel-in-progress: false + +# Set the environment variables to be used in all jobs defined in this workflow +env: + # CI_BRANCH - the branch name (used in mkdocs.yml) + # For PRs: github.head_ref is the source branch + # For pushes: github.ref_name is the branch + # For tags: github.ref_name is the tag name + # GITHUB_REPOSITORY - the repository name (used in mkdocs.yml) + # NOTEBOOKS_DIR - the directory containing the Jupyter notebooks (used in mkdocs.yml) + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + DEVELOP_BRANCH: develop + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + IS_RELEASE_TAG: ${{ startsWith(github.ref, 'refs/tags/v') }} + GITHUB_REPOSITORY: ${{ github.repository }} + NOTEBOOKS_DIR: tutorials + +jobs: + # Single job that builds and deploys documentation. + # Uses macOS runner for consistent Plotly chart rendering. + build-deploy-docs: + runs-on: ubuntu-latest # macos-latest + + permissions: + contents: write # Required for pushing to the gh-pages branch + + steps: + # Setting DOCS_VERSION to be used in mkdocs.yml, and then in the + # main.html template. It defines the versioned docs subfolder name + # in the gh-pages branch. If it's a release tag, use the version + # number without the 'v' prefix, otherwise use 'dev'. + # Setting RELEASE_VERSION to be used in mkdocs.yml to show + # the latest release version in the index.md file. If it's a + # release tag, use the tag name, otherwise use the branch name + # for development builds. + - name: Set extra env variables + shell: bash + run: | + if [[ "${IS_RELEASE_TAG}" == "true" ]]; then + RELEASE_VERSION="${GITHUB_REF_NAME}" + DOCS_VERSION="${RELEASE_VERSION#v}" + else + RELEASE_VERSION="${CI_BRANCH}" + DOCS_VERSION="dev" + fi + echo "RELEASE_VERSION=${RELEASE_VERSION}" >> "$GITHUB_ENV" + echo "DOCS_VERSION=${DOCS_VERSION}" >> "$GITHUB_ENV" + + # Check out the repository source code. + # Note: The gh-pages branch is fetched separately later for mike deployment. + - name: Checkout repository + uses: actions/checkout@v5 + + # Activate dark mode to create documentation with Plotly charts in dark mode + # Need a better solution to automatically switch the chart colour theme based on the mkdocs material switcher + # Something similar to mkdocs_plotly_plugin https://haoda-li.github.io/mkdocs-plotly-plugin/, + # but for generating documentation from notepads + #- name: Activate dark mode + # run: | + # brew install dark-mode + # dark-mode status + # dark-mode on + # dark-mode status + + # Set up the pixi package manager and install dependencies from pixi.toml. + # Uses frozen lockfile to ensure reproducible builds. + - name: Set up pixi + uses: ./.github/actions/setup-pixi + # Pre-import the main package to exclude info messages from the docs + # E.g., Matplotlib may print messages to stdout/stderr when first + # imported. This step allows to avoid "Matplotlib is building the font + # cache" messages during notebook execution. + - name: Pre-build site step + run: pixi run python -c "import easyscience" + + # Prepare the Jupyter notebooks for documentation (strip output, etc.). + - name: Prepare notebooks + run: pixi run notebook-prepare + + # Execute all Jupyter notebooks to generate output cells (plots, tables, etc.). + # Uses multiple cores for parallel execution to speed up the process. + - name: Run notebooks + # if: false # Temporarily disabled to speed up the docs build + run: pixi run notebook-exec + + # Build the static files for the documentation site for local inspection + # Input: docs/ directory containing the Markdown files + # Output: site/ directory containing the generated HTML files + - name: Build site for local check + run: pixi run docs-build-local + + # Upload the static files from the site/ directory to be used for + # local check + - name: Upload built site as artifact + uses: ./.github/actions/upload-artifact + with: + name: site-local_easyscience-lib-${{ env.RELEASE_VERSION }} + path: docs/site/ + + # Create GitHub App token for pushing to gh-pages as easyscience[bot]. + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + + # Configure git identity and remote URL so mike pushes as easyscience[bot]. + - name: Configure git for pushing + run: | + set -euo pipefail + git config user.name "easyscience[bot]" + git config user.email "${{ vars.EASYSCIENCE_APP_ID }}+easyscience[bot]@users.noreply.github.com" + git remote set-url origin "https://x-access-token:${{ steps.bot.outputs.token }}@github.com/${{ github.repository }}.git" + + # Fetch the gh-pages branch to ensure mike has the latest remote state. + # This is required because the checkout step only fetches the source branch, + # not the gh-pages branch that mike needs to update. + - name: Fetch gh-pages branch + run: | + git fetch origin gh-pages:gh-pages 2>/dev/null || true + + # Deploy versioned documentation using mike (MkDocs plugin for versioning). + # - For release tags (v*): deploys to versioned folder (e.g., /0.9.1/) and aliases to /latest/. + # - For branches: deploys to /dev/. + # The "${RELEASE_VERSION#v}" syntax strips the 'v' prefix (v0.9.1 -> 0.9.1). + # Also sets 'latest' as the default version for the version selector. + - name: Rebuild and deploy docs with mike + run: | + # Exit on error (-e), undefined vars (-u), and pipeline failures (pipefail) + set -euo pipefail + + REPO_NAME="${{ github.event.repository.name }}" + BASE_URL="https://easyscience.github.io/${REPO_NAME}" + + # Deploy the release version and update the "latest" alias + if [[ "${IS_RELEASE_TAG}" == "true" ]]; then + pixi run docs-deploy-pre "${RELEASE_VERSION#v}" latest + pixi run docs-set-default-pre latest + DEPLOYMENT_URL="${BASE_URL}/latest" + + # Deploy/update the "dev" alias (or whatever your convention is) + else + pixi run docs-deploy-pre dev + DEPLOYMENT_URL="${BASE_URL}/dev" + + fi + + # Add links to the action summary page for easy access + echo "🔗 deployment url [${DEPLOYMENT_URL}](${DEPLOYMENT_URL})" >> "${GITHUB_STEP_SUMMARY}" diff --git a/.github/workflows/documentation-build.yml b/.github/workflows/documentation-build.yml deleted file mode 100644 index 958a8dde..00000000 --- a/.github/workflows/documentation-build.yml +++ /dev/null @@ -1,49 +0,0 @@ -# This pipeline -# - builds developer documentation using pixi -# - pushes documentation to gh-pages branch of the same repository -# -# Deployment is handled by pages-build-deployment bot - -name: Build Documentation and Push to gh-pages Branch - -# Controls when the workflow will run -on: - # Triggers the workflow on tag creation - push: - tags: - - 'v*' - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -permissions: - contents: write - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build_documentation: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 # otherwise, you will failed to push refs to dest repo - - - name: Setup Pixi - uses: prefix-dev/setup-pixi@v0.9.4 - - - name: Build documentation - run: pixi run --environment dev docs-build - - # - name: Build and Commit - # uses: sphinx-notes/pages@master - # with: - # install_requirements: true - # documentation_path: docs/src - - - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs/_build/html diff --git a/.github/workflows/issues-labels.yml b/.github/workflows/issues-labels.yml new file mode 100644 index 00000000..3a60cdd7 --- /dev/null +++ b/.github/workflows/issues-labels.yml @@ -0,0 +1,42 @@ +# Verifies if an issue has at least one of the `[scope]` and one of the +# `[priority]` labels. If not, the bot adds labels with a warning emoji +# to indicate that those labels need to be added. + +name: Issue labels check + +on: + issues: + types: [opened, labeled, unlabeled] + +permissions: + issues: write + +jobs: + check-labels: + runs-on: ubuntu-latest + + steps: + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + + - name: Check for required [scope] label + uses: trstringer/require-label-prefix@v1 + with: + secret: ${{ steps.bot.outputs.token }} + prefix: '[scope]' + labelSeparator: ' ' + addLabel: true + defaultLabel: '[scope] ⚠️ label needed' + + - name: Check for required [priority] label + uses: trstringer/require-label-prefix@v1 + with: + secret: ${{ steps.bot.outputs.token }} + prefix: '[priority]' + labelSeparator: ' ' + addLabel: true + defaultLabel: '[priority] ⚠️ label needed' diff --git a/.github/workflows/lint-format.yml b/.github/workflows/lint-format.yml new file mode 100644 index 00000000..fc451d14 --- /dev/null +++ b/.github/workflows/lint-format.yml @@ -0,0 +1,130 @@ +# The workflow is divided into several steps: +# - Check the validity of pyproject.toml +# - Check code linting +# - Check code formatting +# - Check formatting of docstrings in the code +# - Check formatting of Markdown, YAML, TOML, etc. files + +name: Lint and format checks + +on: + # Trigger the workflow on push + push: + branches-ignore: [master, main] # Already verified in PR + # Do not run this workflow on creating a new tag starting with + # 'v', e.g. 'v1.0.3' (see publish-pypi.yml) + tags-ignore: ['v*'] + # Trigger the workflow on pull request + pull_request: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Allow only one concurrent workflow, skipping runs queued between the run +# in-progress and latest queued. And cancel in-progress runs. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +# Set the environment variables to be used in all jobs defined in this workflow +env: + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + +jobs: + lint-format: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Run post-install developer steps + run: pixi run post-install + + # Check the validity of pyproject.toml + - name: Check validity of pyproject.toml + id: check_pyproject + continue-on-error: true + shell: bash + run: pixi run pyproject-check + + # Check the presence and correctness of SPDX license headers in + # the code files + - name: Check SPDX license headers + id: check_spdx_headers + continue-on-error: true + shell: bash + run: pixi run spdx-check + + # Check code linting with Ruff in the project root + - name: Check code linting + id: check_code_linting + continue-on-error: true + shell: bash + run: pixi run py-lint-check + + # Check code formatting with Ruff in the project root + - name: Check code formatting + id: check_code_formatting + continue-on-error: true + shell: bash + run: pixi run py-format-check + + # Check formatting of docstrings in the code with docformatter + - name: Check formatting of docstrings in the code + id: check_docs_formatting + continue-on-error: true + shell: bash + run: pixi run docs-format-check + + # Check formatting of MD, YAML, TOML, etc. files with Prettier in + # the project root + - name: Check formatting of MD, YAML, TOML, etc. files + id: check_others_formatting + continue-on-error: true + shell: bash + run: pixi run nonpy-format-check + + # Check formatting of Jupyter Notebooks in the tutorials folder + - name: Prepare notebooks and check formatting + id: check_notebooks_formatting + continue-on-error: true + shell: bash + run: pixi run notebook-format-check + + # Add summary + - name: Add quality checks summary + if: always() + shell: bash + run: | + { + echo "## 🧪 Checks Summary" + echo "" + echo "| Check | Status |" + echo "|-------|--------|" + echo "| pyproject.toml | ${{ steps.check_pyproject.outcome == 'success' && '✅' || '❌' }} |" + echo "| SPDX headers | ${{ steps.check_spdx_headers.outcome == 'success' && '✅' || '❌' }} |" + echo "| py lint | ${{ steps.check_code_linting.outcome == 'success' && '✅' || '❌' }} |" + echo "| py format | ${{ steps.check_code_formatting.outcome == 'success' && '✅' || '❌' }} |" + echo "| docstring format | ${{ steps.check_docs_formatting.outcome == 'success' && '✅' || '❌' }} |" + echo "| nonpy format | ${{ steps.check_others_formatting.outcome == 'success' && '✅' || '❌' }} |" + echo "| notebooks format | ${{ steps.check_notebooks_formatting.outcome == 'success' && '✅' || '❌' }} |" + } >> "$GITHUB_STEP_SUMMARY" + + # Fail job if any check failed + - name: Fail job if any check failed + if: | + steps.check_pyproject.outcome == 'failure' + || steps.check_spdx_headers.outcome == 'failure' + || steps.check_code_linting.outcome == 'failure' + || steps.check_code_formatting.outcome == 'failure' + || steps.check_docs_formatting.outcome == 'failure' + || steps.check_others_formatting.outcome == 'failure' + || steps.check_notebooks_formatting.outcome == 'failure' + shell: bash + run: exit 1 diff --git a/.github/workflows/nightly-check.yml b/.github/workflows/nightly-check.yml deleted file mode 100644 index f35a232c..00000000 --- a/.github/workflows/nightly-check.yml +++ /dev/null @@ -1,24 +0,0 @@ -# Nightly Check - install dependencies and run tests after pixi update-lock -name: Nightly Check -on: - schedule: - - cron: '0 0 * * *' # Runs every day at midnight UTC - workflow_dispatch: - -jobs: - nightly-check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - - name: Setup Pixi - uses: prefix-dev/setup-pixi@v0.9.4 - - - name: Update lock file - run: pixi run update-lock - - - name: Build package - run: pixi run build - - - name: Run tox tests - run: pixi run -e dev tox diff --git a/.github/workflows/ossar-analysis.yml b/.github/workflows/ossar-analysis.yml deleted file mode 100644 index 1d4435f4..00000000 --- a/.github/workflows/ossar-analysis.yml +++ /dev/null @@ -1,38 +0,0 @@ -# This workflow integrates a collection of open source static analysis tools -# with GitHub code scanning. For documentation, or to provide feedback, visit -# https://github.com/github/ossar-action -name: OSSAR - -on: - pull_request: - -jobs: - OSSAR-Scan: - # OSSAR runs on windows-latest. - # ubuntu-latest and macos-latest support coming soon - runs-on: windows-latest - - steps: - # Checkout your code repository to scan - - name: Checkout repository - uses: actions/checkout@v5 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 - - # If this run was triggered by a pull request event, then checkout - # the head of the pull request instead of the merge commit. - - run: git checkout HEAD^2 - if: ${{ github.event_name == 'pull_request' }} - - # Run open source static analysis tools - - name: Run OSSAR - uses: github/ossar-action@v1 - id: ossar - - # Upload results to the Security tab - - name: Upload OSSAR results - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: ${{ steps.ossar.outputs.sarifFile }} \ No newline at end of file diff --git a/.github/workflows/pr-labels.yml b/.github/workflows/pr-labels.yml new file mode 100644 index 00000000..642cd318 --- /dev/null +++ b/.github/workflows/pr-labels.yml @@ -0,0 +1,56 @@ +# Verifies if a pull request has at least one label from a set of valid +# labels before it can be merged. +# +# NOTE: +# This workflow may be triggered twice in quick succession when a PR is +# created: +# 1) `opened` — when the pull request is initially created +# 2) `labeled` — if labels are added immediately after creation +# (e.g. by manual labeling, another workflow, or GitHub App). +# +# These are separate GitHub events, so two workflow runs can be started. + +name: PR labels check + +on: + pull_request_target: + types: [opened, labeled, unlabeled, synchronize] + +permissions: + pull-requests: read + +jobs: + check-labels: + runs-on: ubuntu-latest + + steps: + - name: Check for valid labels + run: | + PR_LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r '.[]') + + echo "Current PR labels: $PR_LABELS" + VALID_LABELS=( + "[bot] release" + "[scope] bug" + "[scope] documentation" + "[scope] enhancement" + "[scope] maintenance" + "[scope] significant" + ) + + found=false + for label in "${VALID_LABELS[@]}"; do + if echo "$PR_LABELS" | grep -Fxq "$label"; then + echo "✅ Found valid label: $label" + found=true + break + fi + done + + if [ "$found" = false ]; then + echo "ERROR: PR must have at least one of the following labels:" + for label in "${VALID_LABELS[@]}"; do + echo " - $label" + done + exit 1 + fi diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml new file mode 100644 index 00000000..95a3b394 --- /dev/null +++ b/.github/workflows/pypi-publish.yml @@ -0,0 +1,46 @@ +# Builds a Python package and publish it to PyPI when a new tag is +# created. + +name: PyPI publishing + +on: + # Runs on creating a new tag starting with 'v', e.g. 'v1.0.3' + push: + tags: ['v*'] + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + pypi-publish: + runs-on: ubuntu-latest + + permissions: + contents: read + id-token: write # IMPORTANT: this permission is mandatory for trusted publishing + + steps: + - name: Check-out repository + uses: actions/checkout@v5 + with: + fetch-depth: 0 # full history with tags to get the version number by versioningit + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + # Build the Python package (to dist/ folder) + - name: Create Python package + run: pixi run default-build + + # Publish the package to PyPI (from dist/ folder) + # Instead of publishing with personal access token, we use + # GitHub Actions OIDC to get a short-lived token from PyPI. + # New publisher must be previously configured in PyPI at + # https://pypi.org/manage/project/easyscience/settings/publishing/ + # Use the following data: + # Owner: easyscience + # Repository name: core + # Workflow name: pypi-publish.yml + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: 'dist' diff --git a/.github/workflows/pypi-test.yml b/.github/workflows/pypi-test.yml new file mode 100644 index 00000000..6f4e582f --- /dev/null +++ b/.github/workflows/pypi-test.yml @@ -0,0 +1,80 @@ +name: PyPI package tests + +on: + # Run daily, at 00:00. + schedule: + - cron: '0 0 * * *' + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Allow only one concurrent workflow, skipping runs queued between the run +# in-progress and latest queued. And cancel in-progress runs. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +# Set the environment variables to be used in all jobs defined in this workflow +env: + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + +jobs: + # Job 1: Test installation from PyPI on multiple OS + pypi-package-tests: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + with: + environments: '' + activate-environment: '' + run-install: false + frozen: false + + - name: Init pixi project + run: pixi init easyscience + + - name: Add Python 3.13 from Conda + working-directory: easyscience + run: pixi add "python=3.13" + + - name: Add other Conda dependencies + working-directory: easyscience + run: pixi add gsl + + - name: Add easyscience from PyPI + working-directory: easyscience + run: pixi add --pypi "easyscience" + + - name: Add dev dependencies from PyPI + working-directory: easyscience + run: pixi add --pypi pytest pytest-xdist + + - name: Add Pixi task as a shortcut + working-directory: easyscience + run: pixi task add easyscience "python -m easyscience" + + - name: Run unit tests to verify the installation + working-directory: easyscience + run: pixi run python -m pytest ../tests/unit/ --color=yes -v + + - name: Run integration tests to verify the installation + working-directory: easyscience + run: pixi run python -m pytest ../tests/integration/ --color=yes -n auto + + # Job 2: Build and publish dashboard (reusable workflow) + run-reusable-workflows: + needs: pypi-package-tests # depend on previous job + uses: ./.github/workflows/dashboard.yml + secrets: inherit diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml deleted file mode 100644 index ed16dfdd..00000000 --- a/.github/workflows/python-ci.yml +++ /dev/null @@ -1,94 +0,0 @@ -# This workflow will for a variety of Python versions -# - install the code base with pixi -# - lint the code base -# - test the code base -# - upload the test coverage to codecov -# -# It will also -# - build the package -# - check the package -# -# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries - -name: CI using pixi - -on: [push, pull_request] - -jobs: - Code_Consistency: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - name: Setup Pixi - uses: prefix-dev/setup-pixi@v0.9.4 - - name: Run linting - run: pixi run -e dev lint-check - - - name: Suggestion to fix lint issues - if: ${{ failure() }} - run: | - echo "::notice::In project root run 'pixi run -e dev lint' and commit changes to fix issues." - exit 1 - - - name: Run formatting - run: pixi run -e dev format-check - - - name: Suggestion to fix format issues - if: ${{ failure() }} - run: | - echo "::notice::In project root run 'pixi run -e dev format' and commit changes to fix issues." - exit 1 - - Code_Testing: - strategy: - max-parallel: 4 - matrix: - python-version: ['3.11', '3.12', '3.13'] - os: [ubuntu-latest, macos-latest, macos-15-intel, windows-latest] - - runs-on: ${{ matrix.os }} - if: "!contains(github.event.head_commit.message, '[ci skip]')" - - steps: - - uses: actions/checkout@v5 - - - name: Setup Pixi - uses: prefix-dev/setup-pixi@v0.9.0 - with: - run-install: false - cache: false - post-cleanup: false - - - name: Set Python version - run: pixi add python=${{ matrix.python-version }} - - - name: Install dependencies and run tests - run: pixi run -e dev test - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v5 - with: - name: unit-tests-job - flags: unittests - files: ./coverage-unit.xml - fail_ci_if_error: true - verbose: true - token: ${{ secrets.CODECOV_TOKEN }} - slug: EasyScience/corelib - - Package_Testing: - - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, '[ci skip]')" - - steps: - - uses: actions/checkout@v5 - - - name: Setup Pixi - uses: prefix-dev/setup-pixi@v0.9.4 - - - name: Build package - run: pixi run build - - - name: Run tox tests - run: pixi run -e dev tox diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml deleted file mode 100644 index 9158390b..00000000 --- a/.github/workflows/python-package.yml +++ /dev/null @@ -1,46 +0,0 @@ -# This workflow will for a variety of Python versions -# - build a python package using pixi -# - run tests on the produced package -# - upload the package as an artifact -# -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions - -name: Create Python Package using pixi - - -on: - push: - branches: - - master - pull_request: - branches: - - master - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ['3.11', '3.12', '3.13'] - if: "!contains(github.event.head_commit.message, '[ci skip]')" - - steps: - - uses: actions/checkout@v5 - - - name: Setup Pixi - uses: prefix-dev/setup-pixi@v0.9.4 - - - name: Set Python version - run: pixi add python=${{ matrix.python-version }} - - - name: Build package - run: pixi run build - - - name: Run tests with tox - run: pixi run -e dev tox - - - uses: actions/upload-artifact@v4 - with: - name: EasyScience - Python ${{ matrix.python-version }} - path: ${{ github.workspace }}/dist/* - overwrite: true \ No newline at end of file diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml deleted file mode 100644 index 17a81037..00000000 --- a/.github/workflows/python-publish.yml +++ /dev/null @@ -1,38 +0,0 @@ -# This workflow will -# - build distribution package, pure python wheel using pixi -# - publish produced distribution package to PyPI -# -# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries - -name: Publish Python Package - -# Controls when the workflow will run -on: - # Triggers the workflow on tag creation - push: - tags: - - 'v*' - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -jobs: - deploy: - - runs-on: ubuntu-latest - permissions: - id-token: write - contents: read - steps: - - uses: actions/checkout@v5 - - - name: Setup Pixi - uses: prefix-dev/setup-pixi@v0.9.4 - - - name: Build package - run: pixi run build - - - name: Publish distribution 📦 to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - with: - password: ${{ secrets.PYPI_TOKEN_ES }} diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml new file mode 100644 index 00000000..4dd25dfa --- /dev/null +++ b/.github/workflows/release-notes.yml @@ -0,0 +1,71 @@ +# Drafts your next Release notes as pull requests are merged into +# default branch + +name: Release draft update + +on: + # Runs on pushes targeting the default branch (updates the real draft release) + push: + branches: [master, main] + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + draft-release-notes: + permissions: + # write permission is required to create a github release + contents: write + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + fetch-depth: 0 # full history with tags to get the version number + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + + - name: Drafts the next release notes + id: draft + uses: enhantica/drafterino@v2 + with: + config: | + title: 'easyscience $COMPUTED_VERSION' + tag: 'v$COMPUTED_VERSION' + note-template: '- $PR_TITLE (#$PR_NUMBER)' + + default-bump: post + + major-bump-labels: ['[scope] significant'] + minor-bump-labels: ['[scope] enhancement'] + patch-bump-labels: ['[scope] bug', '[scope] maintenance'] + post-bump-labels: ['[scope] documentation'] + + release-notes: + - title: 'Added' + labels: ['[scope] significant', '[scope] enhancement'] + - title: 'Fixed' + labels: ['[scope] bug'] + - title: 'Changed' + labels: ['[scope] maintenance', '[scope] documentation'] + env: + GITHUB_TOKEN: ${{ steps.bot.outputs.token }} + + - name: Create GitHub draft release + uses: softprops/action-gh-release@v2 + with: + draft: true + tag_name: ${{ steps.draft.outputs.tag_name }} + name: ${{ steps.draft.outputs.release_name }} + body: ${{ steps.draft.outputs.release_notes }} + env: + GITHUB_TOKEN: ${{ steps.bot.outputs.token }} diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml new file mode 100644 index 00000000..7e6fda49 --- /dev/null +++ b/.github/workflows/release-pr.yml @@ -0,0 +1,55 @@ +# This workflow creates an automated release PR from a source branch into the default branch. +# +# Usage: +# - Triggered manually via workflow_dispatch. +# - Creates a PR titled "Release: merge into ". +# - Adds the label "[bot] release" so it is excluded from changelogs. +# - The PR body makes clear that this is automation only (no review needed). + +name: 'Release PR (develop → master)' + +on: + workflow_dispatch: + inputs: + source_branch: + description: 'Source branch to create PR from' + required: false + default: 'develop' + type: string + +permissions: + contents: read + pull-requests: write + +env: + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + SOURCE_BRANCH: ${{ inputs.source_branch || 'develop' }} + +jobs: + create-pull-request: + runs-on: ubuntu-latest + steps: + - name: Checkout ${{ env.SOURCE_BRANCH }} branch + uses: actions/checkout@v5 + with: + ref: ${{ env.SOURCE_BRANCH }} + + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + + - name: Create PR from ${{ env.SOURCE_BRANCH }} to ${{ env.DEFAULT_BRANCH }} + env: + GH_TOKEN: ${{ steps.bot.outputs.token }} + run: | + gh pr create \ + --base ${{ env.DEFAULT_BRANCH }} \ + --head ${{ env.SOURCE_BRANCH }} \ + --title "Release: merge ${{ env.SOURCE_BRANCH }} into ${{ env.DEFAULT_BRANCH }}" \ + --label "[bot] release" \ + --body "This PR is created automatically to trigger the release pipeline. It merges the accumulated changes from \`${{ env.SOURCE_BRANCH }}\` into \`${{ env.DEFAULT_BRANCH }}\`. + + ⚠️ It is labeled \`[bot] release\` and is excluded from release notes and version bump logic." diff --git a/.github/workflows/release_drafter.yml b/.github/workflows/release_drafter.yml deleted file mode 100644 index eb3f34c2..00000000 --- a/.github/workflows/release_drafter.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Release Drafter - -on: - push: - # branches to consider in the event; optional, defaults to all - branches: - - master - -jobs: - update_release_draft: - runs-on: ubuntu-latest - steps: - # Drafts your next Release notes as Pull Requests are merged into "master" - - uses: release-drafter/release-drafter@v6 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 00000000..9b34cccf --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,93 @@ +# Code scanning (CodeQL) for vulnerabilities and insecure coding patterns. +# +# What this workflow does +# - Runs GitHub CodeQL analysis and uploads results to your repository's Security tab. +# - Triggers on PRs (so findings appear as PR checks) and on pushes to `develop`. +# - Runs on a weekly schedule. +# +# Where to find results on GitHub +# - Repository → Security → Code scanning alerts +# (You can filter by tool = CodeQL and by branch.) +# +# Where to configure on GitHub +# - Repository → Settings → Advanced Security +# Enable "GitHub Advanced Security" (if available) and configure CodeQL there. +# - Repository → Security → Code scanning alerts +# This page shows findings produced by this workflow. +# +# Notes about the scheduled run +# - Scheduled workflows are triggered from the repository's *default branch*. +# If your default branch is `master` but you want the scheduled scan to analyze +# `develop`, this workflow checks out `develop` explicitly for scheduled runs. +# +# References +# - CodeQL Action: https://github.com/github/codeql-action +# - Advanced setup docs: https://docs.github.com/en/code-security/code-scanning + +name: Security scans with CodeQL + +on: + # Run on pull requests so results show up as PR checks and code + # scanning alerts. + pull_request: + branches: [master, main, develop] + + # Run on pushes (e.g., after merging PRs). + push: + branches: [master, main, develop] + + # Run weekly. (Cron is in UTC.) + schedule: + - cron: '0 3 * * 1' + +permissions: + contents: read + security-events: write + +jobs: + codeql: + name: Code scanning + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + # Keep this list tight to avoid noise and speed up runs. + language: [python, actions] + + steps: + # Scheduled workflows run from the default branch. + # We explicitly analyze `develop` on the schedule to keep the scan + # focused on the active dev branch. + - name: Checkout repository (scheduled → develop) + if: ${{ github.event_name == 'schedule' }} + uses: actions/checkout@v5 + with: + ref: develop + + - name: Checkout repository + if: ${{ github.event_name != 'schedule' }} + uses: actions/checkout@v5 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 + + print-link: + name: Print results link + runs-on: ubuntu-latest + + needs: codeql + permissions: {} # no special perms needed just to print links + + steps: + - name: Add Code Scanning link to job summary + run: | + echo "## 🔎 CodeQL Results" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "View Code Scanning alerts here:" >> $GITHUB_STEP_SUMMARY + echo "${{ github.server_url }}/${{ github.repository }}/security/code-scanning" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/test-trigger.yml b/.github/workflows/test-trigger.yml new file mode 100644 index 00000000..ecf6b40c --- /dev/null +++ b/.github/workflows/test-trigger.yml @@ -0,0 +1,40 @@ +name: Scheduled code tests trigger + +on: + # Run daily, at 00:00. + schedule: + - cron: '0 0 * * *' + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: + contents: read + +jobs: + code-tests-trigger: + runs-on: ubuntu-latest + + steps: + - name: Checkout develop branch + uses: actions/checkout@v5 + with: + ref: develop + + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + + - name: Dispatch code tests workflow + uses: ./.github/actions/github-script + with: + github-token: ${{ steps.bot.outputs.token }} + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: "test.yml", + ref: "develop" + }); diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..05998190 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,271 @@ +# This is the main workflow for testing the code before and after +# packaging it. +# The workflow is divided into three jobs: +# 1. env-prepare: +# - Prepare the environment for testing +# 2. source-test: +# - Test the code base against the latest code in the repository +# - Create the Python package +# - Upload the Python package for the next job +# 3. package-test: +# - Download the Python package (including extra files) from the previous job +# - Install the downloaded Python package +# - Test the code base against the installed package +# 4. dashboard-build-trigger: +# - Trigger the dashboard build workflow to update the code quality +# metrics on the dashboard + +name: Code and package tests + +on: + # Trigger the workflow on push + push: + branches-ignore: [master, main] # Already verified in PR + # But do not run this workflow on creating a new tag starting with + # 'v', e.g. 'v1.0.3' (see publish-pypi.yml) + tags-ignore: ['v*'] + # Trigger the workflow on pull request + pull_request: + branches: ['**'] + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Need permissions to trigger the dashboard build workflow +permissions: + actions: write + contents: read + +# Allow only one concurrent workflow, skipping runs queued between the run +# in-progress and latest queued. And cancel in-progress runs. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +# Set the environment variables to be used in all jobs defined in this workflow +env: + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + PY_VERSIONS: '3.11 3.13' + PIXI_ENVS: 'py-311-env py-313-env' + +jobs: + # Job 1: Set up environment variables + env-prepare: + runs-on: [ubuntu-latest] + + outputs: + pytest-marks: ${{ steps.set-mark.outputs.pytest_marks }} + + steps: + # Determine if integration tests should be run fully or only the fast ones + # (to save time on branches other than master and develop) + - name: Set mark for integration tests + id: set-mark + run: | + if [[ "${{ env.CI_BRANCH }}" == "master" || "${{ env.CI_BRANCH }}" == "develop" ]]; then + echo "pytest_marks=" >> $GITHUB_OUTPUT + else + echo "pytest_marks=-m fast" >> $GITHUB_OUTPUT + fi + + # Job 2: Test code + source-test: + needs: env-prepare # depend on previous job + + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04, macos-14, windows-2022] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + with: + environments: ${{ env.PIXI_ENVS }} + + - name: Run unit tests + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + env="py-$(echo $py_ver | tr -d .)-env" # Converts 3.11 -> py-311-env + + echo "Running tests in environment: $env" + pixi run --environment $env unit-tests + done + + - name: Run integration tests ${{ needs.env-prepare.outputs.pytest-marks }} + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + env="py-$(echo $py_ver | tr -d .)-env" # Converts 3.11 -> py-311-env + + echo "Running tests in environment: $env" + pixi run --environment $env integration-tests ${{ needs.env-prepare.outputs.pytest-marks }} + done + + # Delete all local tags when not on a tagged commit to force versioningit + # to fall back to the configured default-tag, which is '999.0.0' in our case. + # This is needed for testing the package in the next job, as its version + # must be higher than the PyPI version for pip to prefer the local version. + - name: Force using versioningit default tag (non tagged release) + if: startsWith(github.ref , 'refs/tags/v') != true + run: git tag --delete $(git tag) + + - name: Build package wheels for all Python versions + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + env="py-$(echo $py_ver | tr -d .)-env" # Converts 3.11 -> py-311-env + + echo "Building wheel in environment: $env" + pixi run --environment $env dist-build + + echo "Moving built wheel to dist/py$py_ver/" + pixi run mkdir -p dist/py$py_ver + pixi run mv dist/*.whl dist/py$py_ver/ + done + + - name: Remove Python cache files before uploading + shell: bash + run: pixi run clean-pycache + + # More than one file/dir need to be specified in 'path', to preserve the + # structure of the dist/ directory, not only its contents. + - name: Upload package (incl. extras) for next job + uses: ./.github/actions/upload-artifact + with: + name: easyscience_${{ matrix.os }}_${{ runner.arch }} + path: dist/ + + # Job 3: Test the package + package-test: + needs: source-test # depend on previous job + + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04, macos-14, windows-2022] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Download package (incl. extras) from previous job + uses: ./.github/actions/download-artifact + with: + # name and path should be taken from the upload step of the previous job + name: easyscience_${{ matrix.os }}_${{ runner.arch }} + path: dist/ + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + with: + environments: '' + activate-environment: '' + run-install: false + frozen: false + + - name: Install easyscience from the built wheel + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + echo "Initializing pixi project" + pixi init easyscience_py$py_ver + cd easyscience_py$py_ver + + echo "Adding Python $py_ver" + pixi add "python=$py_ver" + + echo "Adding Conda dependencies" + pixi add gsl + + #echo "Adding PyPI dependencies" + #pixi add --pypi pytest pytest-xdist + + echo "Looking for wheel in ../dist/py$py_ver/" + ls -l "../dist/py$py_ver/" + + whl_path=(../dist/"py$py_ver"/*.whl) + if [[ ! -f "${whl_path[0]}" ]]; then + echo "❌ No wheel found in ../dist/py$py_ver/" + exit 1 + fi + + whl_url="file://$(python -c 'import os,sys; print(os.path.abspath(sys.argv[1]))' "${whl_path[0]}")" + + echo "Adding easyscience from: $whl_url" + pixi add --pypi "easyscience[dev] @ ${whl_url}" + + echo "Exiting pixi project directory" + cd .. + done + + - name: Run unit tests + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + echo "Entering pixi project directory easyscience_py$py_ver" + cd easyscience_py$py_ver + + echo "Running tests" + pixi run python -m pytest ../tests/unit/ --color=yes -v + + echo "Exiting pixi project directory" + cd .. + done + + - name: Run integration tests ${{ needs.env-prepare.outputs.pytest-marks }} + shell: bash + run: | + set -euo pipefail + + for py_ver in $PY_VERSIONS; do + echo + echo "🔹🔸🔹🔸🔹 Python: $py_ver 🔹🔸🔹🔸🔹" + + echo "Entering pixi project directory easyscience_py$py_ver" + cd easyscience_py$py_ver + + echo "Running tests" + pixi run python -m pytest ../tests/integration/ --color=yes -n auto -v ${{ needs.env-prepare.outputs.pytest-marks }} + + echo "Exiting pixi project directory" + cd .. + done + + # Job 4: Build and publish dashboard (reusable workflow) + run-reusable-workflows: + needs: package-test # depend on previous job + uses: ./.github/workflows/dashboard.yml + secrets: inherit diff --git a/.github/workflows/tutorial-tests-trigger.yml b/.github/workflows/tutorial-tests-trigger.yml new file mode 100644 index 00000000..1bc27f4f --- /dev/null +++ b/.github/workflows/tutorial-tests-trigger.yml @@ -0,0 +1,40 @@ +name: Scheduled tutorial tests trigger + +on: + # Run daily, at 00:00. + schedule: + - cron: '0 0 * * *' + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: + contents: read + +jobs: + tutorial-tests-trigger: + runs-on: ubuntu-latest + + steps: + - name: Checkout develop branch + uses: actions/checkout@v5 + with: + ref: develop + + - name: Setup easyscience[bot] + id: bot + uses: ./.github/actions/setup-easyscience-bot + with: + app-id: ${{ vars.EASYSCIENCE_APP_ID }} + private-key: ${{ secrets.EASYSCIENCE_APP_KEY }} + + - name: Dispatch tutorial tests workflow + uses: ./.github/actions/github-script + with: + github-token: ${{ steps.bot.outputs.token }} + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: "tutorial-tests.yml", + ref: "develop" + }); diff --git a/.github/workflows/tutorial-tests.yml b/.github/workflows/tutorial-tests.yml new file mode 100644 index 00000000..4c9244d0 --- /dev/null +++ b/.github/workflows/tutorial-tests.yml @@ -0,0 +1,64 @@ +name: Tutorial tests + +on: + # Trigger the workflow on push + push: + # Selected branches + branches: [develop] # master and main are already verified in PR + # Trigger the workflow on pull request + pull_request: + branches: ['**'] + # Trigger the workflow on workflow_call (to be called from other workflows) + # Needed, as standard schedule triggers the master branch only, but we want + # to run this workflow on develop branch. + workflow_call: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: + contents: read + +# Allow only one concurrent workflow, skipping runs queued between the run +# in-progress and latest queued. And cancel in-progress runs. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +# Set the environment variables to be used in all jobs defined in this workflow +env: + CI_BRANCH: ${{ github.head_ref || github.ref_name }} + +jobs: + # Job 1: Test tutorials as scripts and notebooks on multiple OS + tutorial-tests: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Set up pixi + uses: ./.github/actions/setup-pixi + + - name: Test tutorials as python scripts + shell: bash + run: pixi run script-tests + + - name: Prepare notebooks + shell: bash + run: pixi run notebook-prepare + + - name: Test tutorials as notebooks + shell: bash + run: pixi run notebook-tests + + # Job 2: Build and publish dashboard (reusable workflow) + run-reusable-workflows: + needs: tutorial-tests # depend on previous job + uses: ./.github/workflows/dashboard.yml + secrets: inherit diff --git a/.github/workflows/verify_issue_labels.yml b/.github/workflows/verify_issue_labels.yml deleted file mode 100644 index 4315fe7e..00000000 --- a/.github/workflows/verify_issue_labels.yml +++ /dev/null @@ -1,33 +0,0 @@ -# This workflow will verify that all issues have at -# least one of the [scope] labels and one of the [priority] labels - -name: Verify issue labels -on: - issues: - types: [opened, labeled, unlabeled] - -jobs: - check_issue_labels: - runs-on: ubuntu-latest - permissions: - issues: write - steps: - - name: Require [scope] label - uses: trstringer/require-label-prefix@v1 - with: - secret: ${{ github.TOKEN }} - prefix: "[scope]" - labelSeparator: " " - addLabel: true - defaultLabel: "[scope] ⚠️ label needed" - - - name: Require [priority] label - if: always() - uses: trstringer/require-label-prefix@v1 - with: - secret: ${{ github.TOKEN }} - prefix: "[priority]" - labelSeparator: " " - addLabel: true - defaultLabel: "[priority] ⚠️ label needed" - diff --git a/.github/workflows/verify_pr_labels.yml b/.github/workflows/verify_pr_labels.yml deleted file mode 100644 index e7eb0f5c..00000000 --- a/.github/workflows/verify_pr_labels.yml +++ /dev/null @@ -1,23 +0,0 @@ -# This workflow will verify that all PRs have at -# least one of the [scope] labels before they can be merged. - -name: Verify PR labels -on: - pull_request_target: - types: [opened, labeled, unlabeled, synchronize] - -jobs: - check_pr_label: - runs-on: ubuntu-latest - permissions: - pull-requests: write - name: Verify that the PR has a valid label - steps: - - name: Verify PR label action - uses: jesusvasquez333/verify-pr-label-action@v1.4.0 - id: verify-pr-label - with: - github-token: ${{ github.TOKEN }} - valid-labels: '[scope] bug, [scope] enhancement, [scope] documentation, [scope] significant, [scope] maintenance' - pull-request-number: ${{ github.event.pull_request.number }} - disable-reviews: false diff --git a/.gitignore b/.gitignore index 5d0e0e91..0500ede3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,52 +1,45 @@ -# QtCreator -*.autosave - -# QtCreator Qml -*.qmlproject.user -*.qmlproject.user.* - -# QtCreator Python -*.pyproject.user -*.pyproject.user.* - -# QtCreator CMake -CMakeLists.txt.user* - # Python -__pycache__ -.venv +__pycache__/ +.venv/ .coverage .pyc -# Poetry -dist -poetry.lock -*.egg-info - # Pixi .pixi/ # PyInstaller -build +dist/ +build/ *.spec -# Jupyter +# MkDocs +docs/site/ + +# Jupyter Notebooks .ipynb_checkpoints +# Node +node_modules/ + +# QtCreator +*.autosave +*.qmlproject.user +*.qmlproject.user.* +*.pyproject.user +*.pyproject.user.* +CMakeLists.txt.user* + +# PyCharm +.idea/ + +# VS Code +.vscode/ + # macOS .DS_Store *.app *.dmg -# Docs -docs/_build - -# VSCode -.vscode - # Misc -..* *.log *.zip -.ci/ -.idea/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 16fd4a4f..feb102db 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,23 +1,61 @@ repos: -- repo: https://github.com/psf/black - rev: 22.3.0 - hooks: - - id: black - exclude: ^dist/ + - repo: local + hooks: + # ------------- + # Manual checks + # ------------- + - id: pixi-pyproject-check + name: pixi run pyproject-check + entry: pixi run pyproject-check + language: system + pass_filenames: false + stages: [manual] -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 # Use the ref you want to point at - hooks: - - id: trailing-whitespace - - id: check-yaml - - id: check-xml - - id: check-toml - - id: pretty-format-json - - id: detect-private-key -- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks - rev: v2.5.0 - hooks: - - id: pretty-format-yaml - args: [--autofix, --indent, '2'] - #- id: pretty-format-toml - # args: [--autofix] + - id: spdx-headers-check + name: pixi run spdx-check + entry: pixi run spdx-check + language: system + pass_filenames: false + stages: [manual] + + - id: pixi-py-lint-check + name: pixi run py-lint-check + entry: pixi run py-lint-check + language: system + pass_filenames: false + stages: [manual] + + - id: pixi-py-format-check + name: pixi run py-format-check + entry: pixi run py-format-check + language: system + pass_filenames: false + stages: [manual] + + - id: pixi-nonpy-format-check + name: pixi run nonpy-format-check + entry: pixi run nonpy-format-check + language: system + pass_filenames: false + stages: [manual] + + - id: pixi-docs-format-check + name: pixi run docs-format-check + entry: pixi run docs-format-check + language: system + pass_filenames: false + stages: [manual] + + - id: pixi-notebook-format-check + name: pixi run notebook-format-check + entry: pixi run notebook-format-check + language: system + pass_filenames: false + stages: [manual] + + - id: pixi-unit-tests + name: pixi run unit-tests + entry: pixi run unit-tests + language: system + pass_filenames: false + stages: [manual] diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..788ec8fa --- /dev/null +++ b/.prettierignore @@ -0,0 +1,17 @@ +# Copier +.copier-answers*.yml + +# Pixi +.pixi +pixi.lock + +# MkDocs +docs/overrides/ +docs/site/ +docs/docs/assets/ + +# Python +.pytest_cache/ + +# MyPy +.mypy_cache diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cb8357ab..fa245c37 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,134 +1,406 @@ -# Contributing +# Contributing to EasyScience -When contributing to the EasyScience repository, please first discuss the change you wish to make via issue, -email, or any other method with the owners of this repository before making a change. +Thank you for your interest in contributing to **EasyScience**! -Please note we have a code of conduct, please follow it in all your interactions with the project. +This guide explains how to: -## Development Setup +- Report issues +- Contribute code +- Improve documentation +- Suggest enhancements +- Interact with the EasyScience community -We use [pixi](https://pixi.sh) for dependency management and development workflow automation. This ensures consistent environments across different platforms and simplifies the development process. +Whether you are an experienced developer or contributing for the first +time, this document walks you through the entire process step by step. -### Prerequisites +Please make sure you follow the EasyScience organization-wide +[Code of Conduct](https://github.com/easyscience/.github/blob/master/CODE_OF_CONDUCT.md). -1. Install pixi following the [official installation guide](https://pixi.sh/latest/#installation) +--- -### Getting Started +## Table of Contents + +- [How to Interact With This Project](#how-to-interact-with-this-project) +- [1. Understanding the Development Model](#1-understanding-the-development-model) +- [2. Getting the Code](#2-getting-the-code) +- [3. Setting Up the Development Environment](#3-setting-up-the-development-environment) +- [4. Creating a Branch](#4-creating-a-branch) +- [5. Implementing Your Changes](#5-implementing-your-changes) +- [6. Code Quality Checks](#6-code-quality-checks) +- [7. Opening a Pull Request](#7-opening-a-pull-request) +- [8. Continuous Integration (CI)](#8-continuous-integration-ci) +- [9. Code Review](#9-code-review) +- [10. Documentation Contributions](#10-documentation-contributions) +- [11. Reporting Issues](#11-reporting-issues) +- [12. Security Issues](#12-security-issues) +- [13. Releases](#13-releases) + +--- + +## How to Interact With This Project + +If you are not planning to modify the code, you may want to: + +- 🐞 Report a bug — see [Reporting Issues](#11-reporting-issues) +- 🛡 Report a security issue — see + [Security Issues](#12-security-issues) +- 💬 Ask a question or start a discussion at + [Project Discussions](https://github.com/easyscience/core/discussions) + +If you plan to contribute code or documentation, continue below. + +--- + +## 1. Understanding the Development Model + +Before you start coding, it is important to understand how development +works in this project. + +### Branching Strategy + +We use the following branches: + +- `master` — stable releases only +- `develop` — active development branch +- Short-lived branches — one branch per contribution + +All normal contributions must target the `develop` branch. + +This means: + +- Do **not** open Pull Requests against `master` +- Always create your branch from `develop` +- Always target `develop` when opening a Pull Request + +See ADR easyscience/.github#12 for full details on the branching +strategy. + +--- + +## 2. Getting the Code + +### 2.1. If You Are an External Contributor + +If you are not a core maintainer of this repository, follow these steps. + +1. Open the repository page: `https://github.com/easyscience/core` + +2. Click the **Fork** button (top-right corner). This creates your own + copy of the repository. + +3. Clone your fork locally: + + ```bash + git clone https://github.com//core.git + cd core + ``` + +4. Add the original repository as `upstream`: + + ```bash + git remote add upstream https://github.com/easyscience/core.git + ``` + +5. Switch to the `develop` branch and update it: + + ```bash + git fetch upstream + git checkout develop + git pull upstream develop + ``` + +If you have contributed before, make sure your local `develop` branch is +up to date before starting new work. You can update it with: -1. Fork and clone the repository: ```bash -git clone https://github.com/your-username/EasyScience.git -cd EasyScience +git fetch upstream +git pull upstream develop ``` -2. Set up the development environment: +This ensures you are working on the latest version of the project. + +### 2.2. If You Are a Core Team Member + +Core team members do not need to fork the repository. You can create a +new branch directly from `develop`, but the rest of the workflow remains +the same. + +--- + +## 3. Setting Up the Development Environment + +You need: + +- Git +- Pixi + +EasyScience projects use **Pixi** to manage the development environment. + +To install Pixi, follow the official instructions: +https://pixi.prefix.dev/latest/installation/ + +You do **not** need to manually install Python. Pixi automatically: + +- Creates the correct Python environment +- Installs all required dependencies +- Installs development tools (linters, formatters, test tools) + +Set up the environment: + ```bash pixi install +pixi run post-install +``` + +After this step, your development environment is ready. + +See ADR easyscience/.github#63 for more details about this decision. + +--- + +## 4. Creating a Branch + +Never work directly on `develop`. + +Create a new branch: + +```bash +git checkout -b my-change +``` + +Use a clear and descriptive name, for example: + +- `improve-solver-speed` +- `fix-boundary-condition` +- `add-tutorial-example` + +Clear branch names make reviews and history easier to understand. + +--- + +## 5. Implementing Your Changes + +While developing: + +- Make small, logical commits +- Write clear and descriptive commit messages +- Follow the Google docstring convention +- Add or update unit tests if behavior changes + +Example: + +```bash +git add . +git commit -m "Improve performance of time integrator for large systems" +``` + +Run tests locally: + +```bash +pixi run unit-tests +``` + +Running tests frequently is strongly recommended. + +--- + +## 6. Code Quality Checks + +Before opening a Pull Request, always run: + +```bash +pixi run check +``` + +This command runs: + +- Formatting checks +- Linting +- Docstring validation +- Notebook checks +- Unit tests +- Other project validations + +A successful run should look like this: + +```bash +pixi run pyproject-check...................................Passed +pixi run py-lint-check.....................................Passed +pixi run py-format-check...................................Passed +pixi run nonpy-format-check................................Passed +pixi run docs-format-check.................................Passed +pixi run notebook-format-check.............................Passed +pixi run unit-tests........................................Passed +``` + +If something fails, read the error message carefully and fix the issue. + +You can run individual checks, for example: + +```bash +pixi run py-lint-check +``` + +Some formatting issues can be fixed automatically: + +```bash +pixi run fix ``` -3. Run tests to verify everything is working: +If everything is correctly formatted, you will see: + +```text +✅ All code auto-formatting steps have been applied. +``` + +This indicates that the auto-formatting pipeline completed successfully. +If you do not see this message and no error messages appear, try running +the command again. + +If errors are reported, resolve them and re-run: + ```bash -pixi run test +pixi run check ``` -### Development Workflow +All checks must pass before your Pull Request can be merged. + +If you are unsure how to fix an issue, ask for help in your Pull Request +discussion. -- **Run tests**: `pixi run test` (full test suite with coverage) -- **Run unit tests only**: `pixi run test-unit` -- **Check code style**: `pixi run lint-check` -- **Fix code style**: `pixi run lint` -- **Check code formatting**: `pixi run format-check` -- **Format code**: `pixi run format` -- **Build package**: `pixi run build` -- **Build documentation**: `pixi run docs-build` +--- -### Before Submitting a Pull Request +## 7. Opening a Pull Request -1. Update the lock file to ensure dependencies are up to date: `pixi run update-lock` -2. Ensure all tests pass: `pixi run test` -3. Check code style: `pixi run lint-check` -4. Format your code: `pixi run format` -5. Update documentation if necessary -6. Add tests for new functionality +Push your branch: -## Pull Request Process +```bash +git push origin my-change +``` -1. Ensure any install or build dependencies are removed before the end of the layer when doing a - build. -2. Update the README.md with details of changes to the interface, this includes new environment - variables, exposed ports, useful file locations and container parameters. -3. Increase the version numbers in any examples files and the README.md to the new version that this - Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). -4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you - do not have permission to do that, you may request the second reviewer to merge it for you. +On GitHub: -## Code of Conduct +- Click **Compare & Pull Request** +- Ensure the base branch is `develop` +- Write a clear and concise title +- Add a description explaining what changed and why +- Add the required `[scope]` label -### Our Pledge +### Pull Request Title -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -nationality, personal appearance, race, religion, or sexual identity and -orientation. +The PR title appears in release notes and changelogs. It should be +concise and informative. + +Good examples: + +- Improve performance of time integrator for large systems +- Fix incorrect boundary condition handling in solver +- Add adaptive step-size control to ODE solver +- Add tutorial for custom model configuration +- Refactor solver API for improved readability + +### Required `[scope]` Label + +Each Pull Request must include one `[scope]` label: + +| Label | Description | +| ----------------------- | ----------------------------------------------------------------------- | +| `[scope] bug` | Bug report or fix (major.minor.**PATCH**) | +| `[scope] documentation` | Documentation-only changes (major.minor.patch.**POST**) | +| `[scope] enhancement` | Adds or improves features (major.**MINOR**.patch) | +| `[scope] maintenance` | Code/tooling cleanup without feature or bug fix (major.minor.**PATCH**) | +| `[scope] significant` | Breaking or major changes (**MAJOR**.minor.patch) | + +See ADR easyscience/.github#33 for full versioning rules. + +--- + +## 8. Continuous Integration (CI) + +After opening a Pull Request: + +- Automated checks run automatically +- You will see green checkmarks or red crosses + +If checks fail: + +1. Open the failing check +2. Read the logs +3. Fix the issue locally +4. Run `pixi run check` +5. Push your changes + +The Pull Request updates automatically. + +--- + +## 9. Code Review + +All Pull Requests are reviewed by at least one core team member. + +Code review is collaborative and aims to improve quality. + +Do not take comments personally — they are meant to help. + +To update your PR: + +```bash +git add . +git commit -m "Address review comments" +git push +``` + +--- + +## 10. Documentation Contributions + +If your change affects users, update the documentation. + +This may include: + +- API documentation +- Examples +- Tutorials +- Jupyter notebooks + +Preview documentation locally: + +```bash +pixi run docs-serve +``` -### Our Standards +Open the URL shown in the terminal to review your changes. -Examples of behavior that contributes to creating a positive environment -include: +--- -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community +## 11. Reporting Issues -Examples of unacceptable behavior by participants include: +If you find a bug but do not want to fix it: -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting +- Search existing issues first +- Provide clear reproduction steps +- Include logs and environment details -### Our Responsibilities +Clear issue reports help maintainers significantly. -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. +--- -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. +## 12. Security Issues -### Scope +Do **not** report security vulnerabilities publicly. -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. +If you discover a potential vulnerability, contact the maintainers +privately. -### Enforcement +--- -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at suport@easydiffraction.org. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. +## 13. Releases -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. +Releases are created by merging `develop` into `master`. -### Attribution +Once your contribution is merged into `develop`, it will be included in +the next stable release. -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] +--- -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ +Thank you for contributing to EasyScience and the EasyScience ecosystem! diff --git a/LICENSE b/LICENSE index f21bf746..c4e3e48e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,6 @@ BSD 3-Clause License -Copyright (c) 2025, Easyscience contributors (https://github.com/EasyScience) -All rights reserved. +Copyright (c) 2021-2026 EasyScience contributors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.md b/README.md index b41a80be..15bf48f8 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,44 @@ -[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md) -[![PyPI badge](http://img.shields.io/pypi/v/EasyScience.svg)](https://pypi.python.org/pypi/EasyScience) -[![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](LICENSE) -[![codecov](https://codecov.io/github/EasyScience/corelib/graph/badge.svg?token=wc6Q0j0Q9t)](https://codecov.io/github/EasyScience/corelib) - -# Easyscience - -## About - -EasyScience package is the foundation of the EasyScience family of projects, providing the building blocks for libraries and applications -which aim to make scientific data simulation and analysis easier. - -## Install - -**EasyScience** can be downloaded using pip: - -```pip install easyscience``` - -Or direct from the repository: - -```pip install https://github.com/easyScience/EasyScience``` - -### Development - -For development setup and workflow instructions, please see [CONTRIBUTING.md](CONTRIBUTING.md). - -## Test - -After installation, launch the test suite: - -```python -m pytest``` - -## Documentation - -Documentation can be found at: - -[https://easyScience.github.io/corelib](https://easyScience.github.io/corelib) - -## Contributing -We absolutely welcome contributions. **EasyScience** is maintained by the ESS and on a volunteer basis and thus we need to foster a community that can support user questions and develop new features to make this software a useful tool for all users while encouraging every member of the community to share their ideas. - -## License -While **EasyScience** is under the BSD-3 license, DFO-LS is subject to the GPL license. - - +

+ + + + + + + EasyScience + +

+ +**EasyScience** is the foundation of the framework, providing reusable +building blocks for scientific libraries and applications aimed at +making data analysis easier. + + + +**EasyScience** is developed as a Python library. + +License: +[BSD 3-Clause](https://github.com/easyscience/core/blob/master/LICENSE) + +## Useful Links + +### For Users + +- 📖 [Documentation](https://easyscience.github.io/core/latest) +- 🚀 + [Getting Started](https://easyscience.github.io/core/latest/introduction) +- 🧪 [Tutorials](https://easyscience.github.io/core/latest/tutorials) +- 💬 + [Get in Touch](https://easyscience.github.io/core/latest/introduction/#get-in-touch) +- 🧾 + [Citation](https://easyscience.github.io/core/latest/introduction/#citation) + +### For Contributors + +- 🧑‍💻 [Source Code](https://github.com/easyscience/core) +- 🐞 [Issue Tracker](https://github.com/easyscience/core/issues) +- 💡 [Discussions](https://github.com/easyscience/core/discussions) +- 🤝 + [Contributing Guide](https://github.com/easyscience/core/blob/master/CONTRIBUTING.md) +- 🛡 + [Code of Conduct](https://github.com/easyscience/.github/blob/master/CODE_OF_CONDUCT.md) diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 00000000..f62b13ab --- /dev/null +++ b/codecov.yml @@ -0,0 +1,13 @@ +# Codecov configuration +# https://docs.codecov.com/docs/codecovyml-reference + +coverage: + status: + project: + default: + # Make project coverage informational (won't block PR) + informational: true + patch: + default: + # Require patch coverage but with threshold + threshold: 1% diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 1a27587e..00000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -SPHINXPROJ = EasyScience -SOURCEDIR = ./src -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/docs/api-reference/base_classes.md b/docs/docs/api-reference/base_classes.md new file mode 100644 index 00000000..687749a2 --- /dev/null +++ b/docs/docs/api-reference/base_classes.md @@ -0,0 +1 @@ +::: easyscience.base_classes diff --git a/docs/docs/api-reference/fitting.md b/docs/docs/api-reference/fitting.md new file mode 100644 index 00000000..ca21c5e6 --- /dev/null +++ b/docs/docs/api-reference/fitting.md @@ -0,0 +1 @@ +::: easyscience.fitting diff --git a/docs/docs/api-reference/global_object.md b/docs/docs/api-reference/global_object.md new file mode 100644 index 00000000..6e6987a8 --- /dev/null +++ b/docs/docs/api-reference/global_object.md @@ -0,0 +1 @@ +::: easyscience.global_object diff --git a/docs/docs/api-reference/index.md b/docs/docs/api-reference/index.md new file mode 100644 index 00000000..4bd6f561 --- /dev/null +++ b/docs/docs/api-reference/index.md @@ -0,0 +1,26 @@ +--- +icon: material/code-braces-box +--- + +# :material-code-braces-box: API Reference + +This section contains the reference detailing the functions and modules +available in EasyScience. + +- [base_classes](base_classes.md) – Core abstract and helper base + classes used to build EasyScience objects (e.g. `ObjBase`, + `ModelBase`). +- [fitting](fitting.md) – Fitting utilities and interfaces, including + `Fitter` and available minimizers. +- [global_object](global_object.md) – Global singleton providing shared + services (logger, map, undo/redo stack, script manager). +- [io](io.md) – Serialization and deserialization framework for + persisting EasyScience objects (serializers and components). +- [job](job.md) – Job and experiment abstractions for running and + organizing analyses. +- [models](models.md) – Predefined model implementations (e.g. + polynomial models) used in fitting workflows. +- [utils](utils.md) – Miscellaneous utility functions and helpers (class + tools, decorators, type helpers). +- [variable](variable.md) – Descriptor types and variable abstractions + (e.g. `DescriptorNumber`, `Parameter`, `DescriptorArray`). diff --git a/docs/docs/api-reference/io.md b/docs/docs/api-reference/io.md new file mode 100644 index 00000000..f06a9356 --- /dev/null +++ b/docs/docs/api-reference/io.md @@ -0,0 +1 @@ +::: easyscience.io diff --git a/docs/docs/api-reference/job.md b/docs/docs/api-reference/job.md new file mode 100644 index 00000000..c743ba62 --- /dev/null +++ b/docs/docs/api-reference/job.md @@ -0,0 +1 @@ +::: easyscience.job diff --git a/docs/docs/api-reference/models.md b/docs/docs/api-reference/models.md new file mode 100644 index 00000000..2471f604 --- /dev/null +++ b/docs/docs/api-reference/models.md @@ -0,0 +1 @@ +::: easyscience.models diff --git a/docs/docs/api-reference/utils.md b/docs/docs/api-reference/utils.md new file mode 100644 index 00000000..d703ac5f --- /dev/null +++ b/docs/docs/api-reference/utils.md @@ -0,0 +1 @@ +::: easyscience.utils diff --git a/docs/docs/api-reference/variable.md b/docs/docs/api-reference/variable.md new file mode 100644 index 00000000..e55a4ee0 --- /dev/null +++ b/docs/docs/api-reference/variable.md @@ -0,0 +1 @@ +::: easyscience.variable diff --git a/docs/docs/assets/images/favicon.png b/docs/docs/assets/images/favicon.png new file mode 100644 index 00000000..1cdd9d9e Binary files /dev/null and b/docs/docs/assets/images/favicon.png differ diff --git a/docs/docs/assets/images/logo_dark.svg b/docs/docs/assets/images/logo_dark.svg new file mode 100644 index 00000000..980c3174 --- /dev/null +++ b/docs/docs/assets/images/logo_dark.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + Logo + + Main circle + + + Inner circles + + + + + + + + Text + + + + + \ No newline at end of file diff --git a/docs/docs/assets/images/logo_light.svg b/docs/docs/assets/images/logo_light.svg new file mode 100644 index 00000000..89b48f9f --- /dev/null +++ b/docs/docs/assets/images/logo_light.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + Logo + + Main circle + + + Inner circles + + + + + + + + Text + + + + + \ No newline at end of file diff --git a/docs/docs/assets/javascripts/extra.js b/docs/docs/assets/javascripts/extra.js new file mode 100644 index 00000000..dd3fc356 --- /dev/null +++ b/docs/docs/assets/javascripts/extra.js @@ -0,0 +1,29 @@ +(function() { + + "use strict" + + // Variables + const header = document.getElementsByTagName('header')[0] + + console.log(window.pageYOffset) + + // Hide-show header shadow + function toggleHeaderShadow() { + if (window.pageYOffset <= 0) { + header.classList.remove("md-header--shadow") + } else { + header.classList.add("md-header--shadow") + } + } + + // Onload + window.onload = function() { + toggleHeaderShadow() + } + + // Onscroll + window.onscroll = function() { + toggleHeaderShadow() + } + +})() diff --git a/docs/docs/assets/javascripts/mathjax.js b/docs/docs/assets/javascripts/mathjax.js new file mode 100644 index 00000000..a92ce69a --- /dev/null +++ b/docs/docs/assets/javascripts/mathjax.js @@ -0,0 +1,27 @@ +window.MathJax = { + tex: { + //inlineMath: [['\\(', '\\)']], + //displayMath: [['\\[', '\\]']], + // Add support for $...$ and \(...\) delimiters + inlineMath: [['$', '$'], ['\\(', '\\)']], + // Add support for $$...$$ and \[...]\ delimiters + displayMath: [['$$', '$$'], ['\\[', '\\]']], + processEscapes: true, + processEnvironments: true + }, + options: { + //ignoreHtmlClass: ".*|", + //processHtmlClass: "arithmatex" + // Skip code blocks only + skipHtmlTags: ['script','noscript','style','textarea','pre','code'], + // Only ignore explicit opt-out + ignoreHtmlClass: 'no-mathjax|tex2jax_ignore', + } +}; + +document$.subscribe(() => { + MathJax.startup.output.clearCache() + MathJax.typesetClear() + MathJax.texReset() + MathJax.typesetPromise() +}) diff --git a/docs/docs/assets/stylesheets/extra.css b/docs/docs/assets/stylesheets/extra.css new file mode 100644 index 00000000..a625be80 --- /dev/null +++ b/docs/docs/assets/stylesheets/extra.css @@ -0,0 +1,359 @@ +/*************/ +/* Variables */ +/*************/ + +:root { + --sz-link-color--lightmode: #0184c7; + --sz-hovered-link-color--lightmode: #37bdf9; + --sz-body-background-color--lightmode: #fafafa; + --sz-body-text-color--lightmode: #525252; + --sz-body-heading-color--lightmode: #434343; + --sz-code-background-color--lightmode: #ececec; + + --sz-link-color--darkmode: #37bdf9; + --sz-hovered-link-color--darkmode: #2890c0; + --sz-body-background-color--darkmode: #262626; + --sz-body-text-color--darkmode: #a3a3a3; + --sz-body-heading-color--darkmode: #e5e5e5; + --sz-code-background-color--darkmode: #212121; +} + +/****************/ +/* Color styles */ +/****************/ + +/* Default styles https://github.com/squidfunk/mkdocs-material/blob/master/src/assets/stylesheets/main/_typeset.scss */ + +/* Light mode */ + +/* Default light mode https://github.com/squidfunk/mkdocs-material/blob/master/src/assets/stylesheets/main/_colors.scss */ + +[data-md-color-scheme="default"] { + + /* Primary color shades */ + --md-primary-fg-color: var(--sz-body-background-color--lightmode); /* Navigation background */ + --md-primary-bg-color: var(--sz-body-text-color--lightmode); /* E.g., Header title and icons */ + --md-primary-bg-color--light: var(--sz-body-text-color--lightmode); /* E.g., Header search */ + + /* Accent color shades */ + --md-accent-fg-color: var(--sz-hovered-link-color--lightmode); /* E.g., Hovered `a` elements & copy icon in code */ + + /* Default color shades */ + --md-default-fg-color: var(--sz-body-text-color--lightmode); + --md-default-fg-color--light: var(--sz-body-heading-color--lightmode); /* E.g., `h1` color & TOC viewed items & `$` in code */ + --md-default-fg-color--lighter: var(--sz-body-text-color--lightmode); /* E.g., `¶` sign near `h1-h8` */ + --md-default-fg-color--lightest: var(--sz-body-text-color--lightmode); /* E.g., Copy icon in code */ + --md-default-bg-color: var(--sz-body-background-color--lightmode); + + /* Code color shades */ + --md-code-bg-color: var(--sz-code-background-color--lightmode); + + /* Typeset color shades */ + --md-typeset-color: var(--sz-body-text-color--lightmode); + + /* Typeset `a` color shades */ + --md-typeset-a-color: var(--sz-link-color--lightmode); + + /* Footer color shades */ + --md-footer-fg-color: var(--sz-body-text-color--lightmode); /* E.g., Next -> */ + --md-footer-fg-color--light: var(--sz-body-text-color--lightmode); /* E.g., © 2022 EasyDiffraction, Material for MkDocs */ + --md-footer-fg-color--lighter: var(--sz-body-text-color--lightmode); /* E.g. Made with */ + --md-footer-bg-color: hsla(0, 0%, 0%, 0.0); /* Space with, e.g., Next -> */ + --md-footer-bg-color--dark: hsla(0, 0%, 0%, 0.0); /* Space with, e.g., © 2022 EasyDiffraction */ + + /* Custom colors */ + --sz-red-color: #F44336; + --sz-blue-color: #03A9F4; + --sz-green-color: #4CAF50; + --sz-orange-color: #FF9800; + + /* Logo display */ + --md-footer-logo-dark-mode: none; + --md-footer-logo-light-mode: block; +} + +/* Dark mode */ + +/* Default dark mode: https://github.com/squidfunk/mkdocs-material/blob/master/src/assets/stylesheets/palette/_scheme.scss */ + +[data-md-color-scheme="slate"] { + + /* Primary color shades */ + --md-primary-fg-color: var(--sz-body-background-color--darkmode); /* Navigation background */ + --md-primary-bg-color: var(--sz-body-text-color--darkmode); /* E.g., Header title and icons */ + --md-primary-bg-color--light: var(--sz-body-text-color--darkmode); /* E.g., Header search */ + + /* Accent color shades */ + --md-accent-fg-color: var(--sz-hovered-link-color--darkmode); /* E.g., Hovered `a` elements & copy icon in code */ + + /* Default color shades */ + --md-default-fg-color: var(--sz-body-text-color--darkmode); + --md-default-fg-color--light: var(--sz-body-heading-color--darkmode); /* E.g., `h1` color & TOC viewed items & `$` in code */ + --md-default-fg-color--lighter: var(--sz-body-text-color--darkmode); /* E.g., `¶` sign near `h1-h8` */ + --md-default-fg-color--lightest: var(--sz-body-text-color--darkmode); /* E.g., Copy icon in code */ + --md-default-bg-color: var(--sz-body-background-color--darkmode); + + /* Code color shades */ + --md-code-bg-color: var(--sz-code-background-color--darkmode); + + /* Typeset color shades */ + --md-typeset-color: var(--sz-body-text-color--darkmode); + + /* Typeset `a` color shades */ + --md-typeset-a-color: var(--sz-link-color--darkmode); + + /* Footer color shades */ + --md-footer-fg-color: var(--sz-body-text-color--darkmode); /* E.g., Next -> */ + --md-footer-fg-color--light: var(--sz-body-text-color--darkmode); /* E.g., © 2022 EasyDiffraction, Material for MkDocs */ + --md-footer-fg-color--lighter: var(--sz-body-text-color--darkmode); /* E.g. Made with */ + --md-footer-bg-color: hsla(0, 0%, 0%, 0.0); /* Space with, e.g., Next -> */ + --md-footer-bg-color--dark: hsla(0, 0%, 0%, 0.0); /* Space with, e.g., © 2022 EasyDiffraction */ + + /* Custom colors */ + --sz-red-color: #EF9A9A; + --sz-blue-color: #81D4FA; + --sz-green-color: #A5D6A7; + --sz-orange-color: #FFCC80; + + /* Logo display */ + --md-footer-logo-dark-mode: block; + --md-footer-logo-light-mode: none; +} + +/*****************/ +/* Custom styles */ +/*****************/ + +/* Logo */ + +#logo_light_mode { + display: var(--md-footer-logo-light-mode); +} + +#logo_dark_mode { + display: var(--md-footer-logo-dark-mode); +} + +/* Customize default styles of MkDocs Material */ + +/* Hide navigation title */ +label.md-nav__title[for="__drawer"] { + height: 0; +} + +/* Hide site title (first topic) while keeping page title and version selector */ +.md-header__topic:first-child .md-ellipsis { + display: none; +} + +/* Increase logo size */ +.md-logo :is(img, svg) { + height: 1.8rem !important; +} + +/* Hide GH repo with counts (top right page corner) */ +.md-header__source { + display: none; +} + +/* Hide GH repo with counts (navigation bar in mobile view) */ +.md-nav__source { + display: none; +} + +/* Ensure all horizontal lines in the navigation list are removed or hidden */ +.md-nav__item { + /* Removes any border starting from the second level */ + border: none !important; + /* Modifies the background color to hide the first horizontal line */ + background-color: var(--md-default-bg-color); +} + +/* Increase TOC (on the right) width */ +.md-nav--secondary { + margin-left: -10px; + margin-right: -4px; +} + +/* */ +.md-nav__item > .md-nav__link { + padding-left: 0.5em; /* Default */ +} + +/* Change line height of the tabel cells */ +.md-typeset td, +.md-typeset th { + line-height: 1.25 !important; +} + +/* Change vertical alignment of the icon inside the tabel cells */ +.md-typeset td .twemoji { + vertical-align: sub !important; +} + +/* Change the width of the primary sidebar */ +/* +.md-sidebar--primary { + width: 240px; +} +*/ + +/* Change the overall width of the page */ +.md-grid { + max-width: 1280px; +} + +/* Needed for mkdocs-jupyter to show download and other buttons on top of the notebook */ +.md-content__button { + position: relative !important; +} + +/* Background color of the search input field */ +.md-search__input { + background-color: var(--md-code-bg-color) !important; +} + +/* Customize default style of mkdocs-jupyter plugin */ + +/* Set the width of the notebook to fill 100% and not reduce by the width of .md-content__button's +Adjust the margins and paddings to fit the defaults in MkDocs Material and do not crop the label in the header +*/ +.jupyter-wrapper { + width: 100% !important; + display: flex !important; +} + +.jp-Notebook { + padding: 0 !important; + margin-top: -3em !important; + + /* Ensure notebook content stretches across the page */ + width: 100% !important; + max-width: 100% !important; + + /* mkdocs-material + some notebook HTML end up as flex */ + align-items: stretch !important; +} + +.jp-Notebook .jp-Cell { + /* Key: flex children often need min-width: 0 to prevent weird shrink */ + width: 100% !important; + max-width: 100% !important; + min-width: 0 !important; + + /* Removes jupyter cell paddings */ + padding-left: 0 !important; +} + +/* Removes jupyter cell prefixes, like In[123]: */ +.prompt, +.jp-InputPrompt, +.jp-OutputPrompt { + display: none !important; +} + +/* Removes jupyter output cell padding to align with input cell text */ +.jp-RenderedText { + padding-left: 0.85em !important; +} + +/* Extra styling the panda dataframes, on top of the style included in the code */ +table.dataframe { + float: left; + margin-left: 0.75em !important; + margin-bottom: 0.5em !important; + font-size: var(--jp-code-font-size) !important; + color: var(--md-primary-bg-color) !important; + /* Allow table cell wrapping in MkDocs-Jupyter outputs */ + /* + table-layout: auto !important; + width: auto !important; + */ +} + +/* Allow wrap for the last column */ +/* +table.dataframe td:last-child, +table.dataframe th:last-child { + white-space: normal !important; + word-break: break-word !important; +} +*/ + +/* Custom styles for the CIF files */ + +.cif { + padding-left: 1em; + padding-right: 1em; + padding-top: 1px; + padding-bottom: 1px; + background-color: var(--md-code-bg-color); + font-size: small; +} +.red { + color: var(--sz-red-color); +} +.green { + color: var(--sz-green-color); +} +.blue { + color: var(--sz-blue-color); +} +.orange { + color: var(--sz-orange-color); +} +.grey { + color: grey; +} + +/**********/ +/* Labels */ +/**********/ + +.label-cif { + padding-top: 0.5ex; + padding-bottom: 0.5ex; + padding-left: 0.9ex; + padding-right: 0.9ex; + border-radius: 1ex; + color: var(--md-default-fg-color) !important; + background-color: var(--md-code-bg-color); +} + +p .label-cif, li .label-cif { + vertical-align: 5%; + font-size: 12px; +} + +.label-cif:hover { + color: white !important; +} + +.label-experiment { + padding-top: 0.25ex; + padding-bottom: 0.6ex; + padding-left: 0.9ex; + padding-right: 0.9ex; + border-radius: 1ex; + color: var(--md-default-fg-color) !important; + background-color: rgba(55, 189, 249, 0.1); +} + +p .label-experiment, li .label-experiment { + vertical-align: 5%; + font-size: 12px; +} + +h1 .label-experiment { + padding-top: 0.05ex; + padding-bottom: 0.4ex; + padding-left: 0.9ex; + padding-right: 0.9ex; + border-radius: 0.75ex; + color: var(--md-default-fg-color) !important; + background-color: rgba(55, 189, 249, 0.1); +} + +.label-experiment:hover { + color: white !important; +} diff --git a/docs/docs/index.md b/docs/docs/index.md new file mode 100644 index 00000000..5a3e9727 --- /dev/null +++ b/docs/docs/index.md @@ -0,0 +1,21 @@ +![](assets/images/logo_dark.svg#gh-dark-mode-only)![](assets/images/logo_light.svg#gh-light-mode-only) + +# Core building blocks for EasyScience + +Here is a brief overview of the main documentation sections: + +- [:material-information-slab-circle: Introduction](introduction/index.md) + – Provides a description of EasyScience, including its purpose, + licensing, latest release details, and contact information. +- [:material-cog-box: Installation & Setup](installation-and-setup/index.md) + – Guides users through system requirements, environment configuration, + and the installation process. +- [:material-book-open-variant: User Guide](user-guide/index.md) – + Covers core concepts, key terminology, workflow steps, and essential + parameters for effective use of EasyScience. +- [:material-school: Tutorials](tutorials/index.md) – Offers practical, + step-by-step examples demonstrating common workflows and data analysis + tasks. +- [:material-code-braces-box: API Reference](api-reference/index.md) – + An auto-generated reference detailing the available functions and + modules in EasyScience. diff --git a/docs/docs/installation-and-setup/index.md b/docs/docs/installation-and-setup/index.md new file mode 100644 index 00000000..64064d08 --- /dev/null +++ b/docs/docs/installation-and-setup/index.md @@ -0,0 +1,281 @@ +--- +icon: material/cog-box +--- + +# :material-cog-box: Installation & Setup + +**EasyScience** is a cross-platform Python library compatible with +**Python 3.11** through **3.13**. + +To install and set up EasyScience, we recommend using +[**Pixi**](https://pixi.prefix.dev), a modern package manager for +Windows, macOS, and Linux. + +??? note "Main benefits of using Pixi" + + - **Ease of use**: Pixi simplifies the installation process, making it + accessible even for users with limited experience in package management. + - **Python version control**: Pixi allows specifying and managing different + Python versions for each project, ensuring compatibility. + - **Isolated environments**: Pixi creates isolated environments for each + project, preventing conflicts between different package versions. + - **PyPI and Conda support**: Pixi can install packages from both PyPI and + Conda repositories, providing access to a wide range of libraries. + +An alternative installation method using the traditional **pip** package +manager is also provided. + +## Installing with Pixi recommended { #installing-with-pixi data-toc-label="Installing with Pixi" } + +This section describes the simplest way to set up EasyScience using +**Pixi**. + +#### Installing Pixi + +- Install Pixi by following the instructions on the + [official Pixi Installation Guide](https://pixi.prefix.dev/latest/installation). + +#### Setting up EasyScience with Pixi + + + +- Choose a project location (local drive recommended). + + ??? warning ":fontawesome-brands-windows: Windows + OneDrive" + + We **do not recommend creating a Pixi project inside OneDrive or other + synced folders**. + + By default, Pixi creates the virtual environment inside the project + directory (in `.pixi/`). On Windows, synced folders such as OneDrive + may cause file‑system issues (e.g., path-length limitations or + restricted link operations), which can lead to unexpected install + errors or environments being recreated. + + Instead, create your project in a **local directory on your drive** + where you have full write permissions. + + + +- Initialize a new Pixi project and navigate into it: + ```txt + pixi init easyscience + cd easyscience + ``` +- Set the Python version for the Pixi environment (e.g., 3.13): + ```txt + pixi add python=3.13 + ``` +- Add EasyScience to the Pixi environment from PyPI: + ```txt + pixi add --pypi easyscience + ``` +- Add a Pixi task to run EasyScience commands easily: + ```txt + pixi task add easyscience "python -m easyscience" + ``` + +#### Updating Pixi and EasyScience + +- To update all packages in the Pixi environment, including EasyScience: + ```txt + pixi update + ``` +- To update Pixi itself to the latest version: + ```txt + pixi self-update + ``` + +#### Uninstalling Pixi + +- Follow the + [official Pixi Guide](https://pixi.prefix.dev/latest/installation/#uninstall). + +## Classical Installation + +This section describes how to install EasyScience using the traditional +method with **pip**. It is assumed that you are familiar with Python +package management and virtual environments. + +### Environment Setup optional { #environment-setup data-toc-label="Environment Setup" } + +We recommend using a **virtual environment** to isolate dependencies and +avoid conflicts with system-wide packages. If any issues arise, you can +simply delete and recreate the environment. + +#### Creating and Activating a Virtual Environment: + + + +- Create a new virtual environment: + ```txt + python3 -m venv venv + ``` +- Activate the environment: + + === ":material-apple: macOS" + ```txt + . venv/bin/activate + ``` + === ":material-linux: Linux" + ```txt + . venv/bin/activate + ``` + === ":fontawesome-brands-windows: Windows" + ```txt + . venv/Scripts/activate # Windows with Unix-like shells + .\venv\Scripts\activate.bat # Windows with CMD + .\venv\Scripts\activate.ps1 # Windows with PowerShell + ``` + +- The terminal should now show `(venv)`, indicating that the virtual environment + is active. + + + +#### Deactivating and Removing the Virtual Environment: + + + +- Exit the environment: + ```txt + deactivate + ``` +- If this environment is no longer needed, delete it: + + === ":material-apple: macOS" + ```txt + rm -rf venv + ``` + === ":material-linux: Linux" + ```txt + rm -rf venv + ``` + === ":fontawesome-brands-windows: Windows" + ```txt + rmdir /s /q venv + ``` + + + +### Installing from PyPI { #from-pypi } + +EasyScience is available on **PyPI (Python Package Index)** and can be +installed using `pip`. To do so, use the following command: + +```txt +pip install easyscience +``` + +To install a specific version of EasyScience, e.g., 1.0.3: + +```txt +pip install 'easyscience==1.0.3' +``` + +To upgrade to the latest version: + +```txt +pip install --upgrade easyscience +``` + +To upgrade to the latest version and force reinstallation of all +dependencies (useful if files are corrupted): + +```txt +pip install --upgrade --force-reinstall easyscience +``` + +To check the installed version: + +```txt +pip show easyscience +``` + +### Installing from GitHub alternative { #from-github data-toc-label="Installing from GitHub" } + +Installing unreleased versions is generally not recommended but may be +useful for testing. + +To install EasyScience from the `develop` branch of GitHub, for example: + +```txt +pip install git+https://github.com/easyscience/core@develop +``` + +To include extra dependencies (e.g., dev): + +```txt +pip install 'easyscience[dev] @ git+https://github.com/easyscience/core@develop' +``` + +## How to Run Tutorials + +EasyScience includes a collection of **Jupyter Notebook examples** that +demonstrate key functionality. These tutorials serve as **step-by-step +guides** to help users understand the data analysis workflow. They are +available as **static HTML pages** in the +[:material-school: Tutorials](../tutorials/index.md) section. + +In the next sections, we explain how to set up Jupyter and run the +tutorials interactively in two different ways: locally or online via +Google Colab. + +If you decide to run the tutorials locally, you need to download them +first. This can be done individually via the :material-download: +**Download Notebook** button available on each tutorial page, or all at +once using the command line, as shown below. + +### Run Tutorials Locally with Pixi recommended { #running-with-pixi data-toc-label="Run Tutorials Locally with Pixi" } + +- Navigate to your existing Pixi project, created as described in the + [Installing with Pixi](#installing-with-pixi) section. +- Add JupyterLab and the Pixi kernel for Jupyter: + ```txt + pixi add --pypi jupyterlab pixi-kernel + ``` +- Download all the EasyScience tutorials to the `tutorials/` directory: + ```txt + pixi run easyscience download-all-tutorials + ``` +- Start JupyterLab in the `tutorials/` directory to access the + notebooks: + ```txt + pixi run jupyter lab tutorials/ + ``` +- Your web browser should open automatically. Click on one of the + `*.ipynb` files and select the `Python (Pixi)` kernel to get started. + +### Classical Run Tutorials Locally + +- Install Jupyter Notebook and IPython kernel: + ```txt + pip install notebook ipykernel + ``` +- Add the virtual environment as a Jupyter kernel: + ```txt + python -m ipykernel install --user --name=venv --display-name "EasyScience Python kernel" + ``` +- Download all the EasyScience tutorials to the `tutorials/` directory: + ```txt + python -m easyscience download-all-tutorials + ``` +- Launch the Jupyter Notebook server (opens browser automatically at + `http://localhost:8888/`): + ```txt + jupyter notebook tutorials/ + ``` +- Open one of the `*.ipynb` files and select the + `EasyScience Python kernel` to get started. + +### Run Tutorials via Google Colab + +**Google Colab** lets you run Jupyter Notebooks in the cloud without any +local installation. This is the fastest way to start experimenting with +EasyScience. + +- Ensure you have a **Google account**. +- Go to the **[:material-school: Tutorials](../tutorials/index.md)** + section. +- Click the :google-colab: **Open in Google Colab** button on any + tutorial. diff --git a/docs/docs/introduction/index.md b/docs/docs/introduction/index.md new file mode 100644 index 00000000..b95b6de3 --- /dev/null +++ b/docs/docs/introduction/index.md @@ -0,0 +1,67 @@ +--- +icon: material/information-slab-circle +--- + +# :material-information-slab-circle: Introduction + +## Description + +**EasyScience** is the foundation of the framework, providing reusable +building blocks for scientific libraries and applications aimed at +making data analysis easier. + +**EasyScience** is developed as a Python library. + + + +## License + +**EasyScience** library is released under the +[BSD 3-Clause License](https://raw.githubusercontent.com/easyscience/core/master/LICENSE). + +## Releases + +The latest version of the **EasyScience** library is +[{{ vars.release_version }}](https://github.com/easyscience/core/releases/latest). + +For a complete list of new features, bug fixes, and improvements, see +the +[GitHub Releases page](https://github.com/easyscience/core/releases). + +## Citation + +If you use **EasyScience** library in your work, please cite the +specific version you used. + +All official releases of the **EasyScience** library are archived on +Zenodo, each with a version-specific Digital Object Identifier (DOI). + +Citation details in various styles (e.g., APA, MLA) and formats (e.g., +BibTeX, JSON) are available on the +[Zenodo archive page](https://doi.org/10.5281/zenodo.18163581). + +## Contributing + +We welcome contributions of any kind! + +**EasyScience** is intended to be a community-driven, open-source +project supported by a diverse group of contributors. + +The project is maintained by the +[European Spallation Source (ESS)](https://ess.eu). + +If you would like to report a bug or request a new feature, please use +the [GitHub Issue Tracker](https://github.com/easyscience/core/issues) +(A free GitHub account is required.) + +To contribute code, documentation, or tests, please see our +[:material-account-plus: Contributing Guidelines](https://github.com/easyscience/core/blob/master/CONTRIBUTING.md) +for detailed development instructions. + +## Get in Touch + +For general questions or feedback, please contact us at +[support@easyscience.org](mailto:support@easyscience.org). diff --git a/docs/docs/tutorials/fitting-qens.ipynb b/docs/docs/tutorials/fitting-qens.ipynb new file mode 100644 index 00000000..a4929a5c --- /dev/null +++ b/docs/docs/tutorials/fitting-qens.ipynb @@ -0,0 +1,359 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "0", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib widget" + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": {}, + "source": [ + "# Fitting QENS data\n", + "\n", + "Some quasi-elastic neutron scattering (QENS) data has been simulated and reduced and can now be analysed with `easyscience`.\n", + "Before the analysis can begin, it is necessary to load the experimental data and check that it looks reasonable. \n", + "The data can be loaded with `np.loadtxt` as the data has been stored in a simple space-separated column file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": {}, + "outputs": [], + "source": [ + "def fetch_data(name: str) -> str:\n", + " \"\"\"\n", + " Fetch pre-prepared data from a remote source and return the path to the file.\n", + " \"\"\"\n", + " import pooch\n", + "\n", + " return pooch.retrieve(\n", + " url=f'https://public.esss.dk/groups/scipp/dmsc-summer-school/2025/{name}',\n", + " known_hash=None,\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "filename = fetch_data('4-reduction/energy_transfer_QENS_unknown_quasi_elastic_many_neutrons.dat')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "def load(filename: str):\n", + " \"\"\"\n", + " Load data from a file. Filter out any NaN values.\n", + " \"\"\"\n", + " x, y, e = np.loadtxt(filename, unpack=True)\n", + " sel = np.isfinite(y)\n", + " return x[sel], y[sel], e[sel]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [ + "q, i, di = load(filename)" + ] + }, + { + "cell_type": "markdown", + "id": "7", + "metadata": {}, + "source": [ + "With the data read in, we can produce a quick plot. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "fig, ax = plt.subplots()\n", + "ax.errorbar(q, i, di, fmt='.')\n", + "ax.set(xlabel='$\\\\omega$/meV', ylabel='$I(\\\\omega)$')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "9", + "metadata": {}, + "source": [ + "The QENS data covers a slightly broader range than we want to investigate.\n", + "Therefore, we will crop the data so that we are only using points between -0.06 and 0.06 meV. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": {}, + "outputs": [], + "source": [ + "sel = (q > -0.06) & (q < 0.06)\n", + "q, i, di = q[sel], i[sel], di[sel]" + ] + }, + { + "cell_type": "markdown", + "id": "11", + "metadata": {}, + "source": [ + "We now want to consider the mathematical model to be used in the analysis. \n", + "QENS data is typically analysed by fitting a Lorentzian function to the data, which has the functional form\n", + "\n", + "$$\n", + "I(\\omega) = \\frac{A\\gamma}{\\pi\\big[(\\omega - \\omega_0) ^ 2 + \\gamma ^ 2\\big]},\n", + "$$ (lorentzian)\n", + "\n", + "where $A$ is a scale factor, $\\gamma$ is the half-width at half-maximum, and $\\omega_0$ is the centre offset. \n", + "\n", + "## Exercise 1: implement a Lorentzian function\n", + "\n", + "Write a function that implements Eqn. {eq}`lorentzian`, called `lorentzian`. \n", + "\n", + "**Solution:**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": {}, + "outputs": [], + "source": [ + "def lorentzian(omega: np.ndarray) -> np.ndarray:\n", + " \"\"\"\n", + " A Lorentzian function.\n", + "\n", + " :omega: the energy transfer values to calculate over.\n", + "\n", + " :return: intensity values.\n", + " \"\"\"\n", + " return A.value / np.pi * gamma.value / ((omega - omega_0.value) ** 2 + gamma.value**2)" + ] + }, + { + "cell_type": "markdown", + "id": "13", + "metadata": {}, + "source": [ + "The instrument has a finite resolution, and to take this into account, the Lorentzian function must be convolved with this resolution. In our case, the resolution is a Gaussian distribution that is centred at zero with width, $\\sigma$. \n", + "In real experiments there are ways to measure $\\sigma$, but for this project, we will simply model it. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14", + "metadata": {}, + "outputs": [], + "source": [ + "from scipy.stats import norm\n", + "\n", + "\n", + "def intensity(omega):\n", + " \"\"\"\n", + " The convolution of a Gaussian and the Lorentzian.\n", + "\n", + " :omega: the energy transfer values to calculate over.\n", + "\n", + " :return: intensity values.\n", + " \"\"\"\n", + " gauss = norm(0, sigma.value).pdf(omega)\n", + " gauss /= gauss.sum()\n", + " return np.convolve(lorentzian(omega), gauss, 'same')" + ] + }, + { + "cell_type": "markdown", + "id": "15", + "metadata": {}, + "source": [ + "This means that there are a total of four parameters in our model. \n", + "\n", + "## Exercise 2: create fitting parameters\n", + "\n", + "Create four `Parameter` objects, for $A$, $\\gamma$, $\\omega_0$, and $\\sigma$.\n", + "\n", + "Each should have an initial value and a uniform prior distribution, based on the values given in {numref}`qens-parameters`." + ] + }, + { + "cell_type": "markdown", + "id": "16", + "metadata": {}, + "source": [ + "| Parameter | Initial Value | Min | Max |\n", + "| --- | --- | --- | --- |\n", + "| $A$ | 10 | 1 | 100 |\n", + "| $\\gamma$ | 8.0 × 10-3 | 1.0 × 10-4 | 1.0 × 10-2 |\n", + "| $\\omega_0$ | 1.0 × 10-3 | 0 | 2.0 × 10-3 |\n", + "| $\\sigma$ | 1.0 × 10-3 | 1.0 × 10-5 | 1.0 × 10-1 |\n" + ] + }, + { + "cell_type": "markdown", + "id": "17", + "metadata": {}, + "source": [ + "**Solution:**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18", + "metadata": {}, + "outputs": [], + "source": [ + "from easyscience import Parameter\n", + "\n", + "A = Parameter(name='A', value=10, fixed=False, min=0.01, max=100)\n", + "gamma = Parameter(name='gamma', value=8e-3, fixed=False, min=1e-4, max=10e-3)\n", + "omega_0 = Parameter(name='omega_0', value=0.001, fixed=False, min=0, max=0.002)\n", + "sigma = Parameter(name='sigma', value=0.001, fixed=False, min=1e-5, max=0.1)" + ] + }, + { + "cell_type": "markdown", + "id": "19", + "metadata": {}, + "source": [ + "It is now possible to compare our model at the initial estimates to the simulated data. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20", + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "ax.errorbar(q, i, di, fmt='.')\n", + "ax.plot(q, intensity(q), '-k', zorder=10)\n", + "ax.set(xlabel='$\\\\omega$/meV', ylabel='$I(\\\\omega)$')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "21", + "metadata": {}, + "source": [ + "## Exercise 3: find maximum likelihood estimates\n", + "\n", + "Using `easyscience`, obtain maximum likelihood estimates for the four parameters of the model from comparison with the data.\n", + "\n", + "**Solution:**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22", + "metadata": {}, + "outputs": [], + "source": [ + "from easyscience import Fitter\n", + "from easyscience import ObjBase\n", + "\n", + "params = ObjBase(name='params', A=A, gamma=gamma, omega_0=omega_0, sigma=sigma)\n", + "f = Fitter(params, intensity)\n", + "\n", + "res = f.fit(x=q, y=i, weights=1 / di)" + ] + }, + { + "cell_type": "markdown", + "id": "23", + "metadata": {}, + "source": [ + "We can then plot the model and the data together as before and print the values of the parameters along with their uncertainties. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24", + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "ax.errorbar(q, i, di, fmt='.')\n", + "ax.plot(q, intensity(q), '-k', zorder=10)\n", + "ax.set(xlabel='$\\\\omega$/meV', ylabel='$I(\\\\omega)$')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25", + "metadata": {}, + "outputs": [], + "source": [ + "A, gamma, omega_0, sigma" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python (Pixi)", + "language": "python", + "name": "pixi-kernel-python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/docs/tutorials/fitting-sans.ipynb b/docs/docs/tutorials/fitting-sans.ipynb new file mode 100644 index 00000000..06b0cc36 --- /dev/null +++ b/docs/docs/tutorials/fitting-sans.ipynb @@ -0,0 +1,349 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "0", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib widget" + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": {}, + "source": [ + "# Fitting SANS data\n", + "\n", + "Some small angle neutron scattering (SANS) data has been simulated and reduced, and can now be analysed with `easyscience`.\n", + "Before the analysis can begin, it is necessary to load the experimental data and check that it looks reasonable. \n", + "The data can be loaded with `np.loadtxt` as the data has been stored in a simple space-separated column file. \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": {}, + "outputs": [], + "source": [ + "def fetch_data(name: str) -> str:\n", + " \"\"\"\n", + " Fetch pre-prepared data from a remote source and return the path to the file.\n", + " \"\"\"\n", + " import pooch\n", + "\n", + " return pooch.retrieve(\n", + " url=f'https://public.esss.dk/groups/scipp/dmsc-summer-school/2025/{name}',\n", + " known_hash=None,\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "filename = fetch_data('4-reduction/sans_iofq.dat')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "def load(filename: str):\n", + " \"\"\"\n", + " Load data from a file. Filter out any NaN values.\n", + " \"\"\"\n", + " x, y, e = np.loadtxt(filename, unpack=True)\n", + " sel = np.isfinite(y)\n", + " return x[sel], y[sel], e[sel]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [ + "q, i, di = load(filename)" + ] + }, + { + "cell_type": "markdown", + "id": "7", + "metadata": {}, + "source": [ + "With the data read in, we can produce a quick plot. \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "fig, ax = plt.subplots()\n", + "ax.errorbar(q, i, di, fmt='.')\n", + "ax.set(yscale='log', xlabel='$q$/Å^-1', ylabel='I(q)')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "9", + "metadata": {}, + "source": [ + "We now want to consider the mathematical model to be used in the analysis. \n", + "There are SANS models a range of different systems, see for instance [the models in SasView](https://www.sasview.org/docs/user/qtgui/Perspectives/Fitting/models/index.html). \n", + "However, initially, we will assume that our data has arisen from a spherical system. \n", + "\n", + "The mathematical model for a sphere is \n", + "\n", + "$$\n", + "I(q) = \\frac{\\text{scale}}{V} \\bigg(\\frac{3 V \\Delta \\rho [\\sin{(qr)} - qr \\cos{(qr)}]}{(qr)^3}\\bigg)^2 + \\text{bkg}, \n", + "$$ (sphere)\n", + "\n", + "where $\\text{scale}$ is a scale factor, $V$ is the volume of the sphere, $\\Delta \\rho$ is the difference between the solvent and particle scattering length density, $r$ is the radius of the sphere, $\\text{bkg}$ is a uniform background, and $q$ is the *q*-vector that the intensity is being calculated for.\n", + "\n", + "## Exercise 1: simplify the expression\n", + "\n", + "The mathematical model described in Eqn. {eq}`sphere` has five parameters. \n", + "What simple mathematical simplification can be performed to reduce this to four?\n", + "\n", + "**Solution:**\n" + ] + }, + { + "cell_type": "markdown", + "id": "10", + "metadata": {}, + "source": [ + "The volume of a sphere is related to the radius of the sphere as\n", + "\n", + "$$\n", + "V = \\frac{4}{3} \\pi r^3. \n", + "$$ (volume-sphere)\n", + "\n", + "Therefore, the parameter $V$ can be replaced with Eqn. {eq}`volume-sphere`.\n" + ] + }, + { + "cell_type": "markdown", + "id": "11", + "metadata": {}, + "source": [ + "## Exercise 2: write a function that computes for the form factor of a sphere\n", + "\n", + "Four parameters is a suitable number for modelling. \n", + "Therefore, we should write a function that implements your reduced dimensionality version of Eqn. {eq}`sphere`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": {}, + "outputs": [], + "source": [ + "def sphere(q):\n", + " \"\"\"\n", + " The function for the form factor of a sphere.\n", + "\n", + " Parameters\n", + " ----------\n", + " q:\n", + " q-vectors to calculate for.\n", + "\n", + " Returns\n", + " -------\n", + " :\n", + " The modelled intensity.\n", + " \"\"\"\n", + " qr = q * r.value\n", + " V = 4 / 3 * np.pi * r.value**3\n", + " return (\n", + " scale.value\n", + " / V\n", + " * (3 * V * delta_rho.value * (np.sin(qr) - qr * np.cos(qr)) / ((qr) ** 3)) ** 2\n", + " + bkg.value\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "13", + "metadata": {}, + "source": [ + "## Exercise 3: create fitting parameters\n", + "\n", + "Create four `Parameter` objects, for $\\text{scale}$, $\\Delta \\rho$,\n", + "$r$, and $\\text{bkg}$.\n", + "\n", + "Each should have an initial value and a uniform prior distribution\n", + "based on the values given in {numref}`sans-parameters`, except for the\n", + "$\\text{scale}$ which should be fixed to a value of 1.4 × 10-7.\n" + ] + }, + { + "cell_type": "markdown", + "id": "14", + "metadata": {}, + "source": [ + "| Parameter | Initial Value | Min | Max |\n", + "| --- | --- | --- | --- |\n", + "| $\\text{scale}$ | 1.4 × 10-7 | N/A | N/A |\n", + "| $\\Delta \\rho$ | 3 | 0 | 10 |\n", + "| $r$ | 80 | 10 | 1000 |\n", + "| $\\text{bkg}$ | 3.0 × 10-3 | 1.0 × 10-3 | 1.0 × 10-2 |\n" + ] + }, + { + "cell_type": "markdown", + "id": "15", + "metadata": {}, + "source": [ + "**Solution:**\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16", + "metadata": {}, + "outputs": [], + "source": [ + "from easyscience import Parameter\n", + "\n", + "scale = Parameter(name='scale', value=1.4e-7, fixed=True)\n", + "delta_rho = Parameter(name='delta_rho', value=3, fixed=False, min=0, max=10)\n", + "r = Parameter(name='r', value=80, fixed=False, min=0, max=1000)\n", + "bkg = Parameter(name='bkg', value=0.01, fixed=False, min=0.001, max=0.1)" + ] + }, + { + "cell_type": "markdown", + "id": "17", + "metadata": {}, + "source": [ + "It is now possible to compare our model at the initial estimates to the simulated data. \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18", + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "ax.errorbar(q, i, di, fmt='.')\n", + "ax.plot(q, sphere(q), '-k', zorder=10)\n", + "ax.set(yscale='log', xlabel='$q$/Å^-1', ylabel='I(q)')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "19", + "metadata": {}, + "source": [ + "## Exercise 4: find maximum likelihood estimates\n", + "\n", + "Using `easyscience`, obtain maximum likelihood estimates for the four parameters of the model from comparison with the data.\n", + "\n", + "**Solution:**\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20", + "metadata": {}, + "outputs": [], + "source": [ + "from easyscience import Fitter\n", + "from easyscience import ObjBase\n", + "\n", + "params = ObjBase(name='params', delta_rho=delta_rho, r=r, bkg=bkg)\n", + "f = Fitter(params, sphere)\n", + "\n", + "res = f.fit(x=q, y=i, weights=1 / di)" + ] + }, + { + "cell_type": "markdown", + "id": "21", + "metadata": {}, + "source": [ + "We can then plot the model and the data together as before and print the values of the parameters along with their uncertainties. \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22", + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "ax.errorbar(q, i, di, fmt='.')\n", + "ax.plot(q, sphere(q), '-k', zorder=10)\n", + "ax.set(yscale='log', xlabel='$q$/Å^-1', ylabel='I(q)')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23", + "metadata": {}, + "outputs": [], + "source": [ + "delta_rho, r, bkg" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python (Pixi)", + "language": "python", + "name": "pixi-kernel-python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/docs/tutorials/index.md b/docs/docs/tutorials/index.md new file mode 100644 index 00000000..8728e9ed --- /dev/null +++ b/docs/docs/tutorials/index.md @@ -0,0 +1,25 @@ +--- +icon: material/school +--- + +# :material-school: Tutorials + +This section presents a collection of **Jupyter Notebook** tutorials +that demonstrate how to use EasyScience for various tasks. These +tutorials serve as self-contained, step-by-step **guides** to help users +grasp the workflow of data analysis using EasyScience. + +Instructions on how to run the tutorials are provided in the +[:material-cog-box: Installation & Setup](../installation-and-setup/index.md#how-to-run-tutorials) +section of the documentation. + +The tutorials are organized into the following categories: + +## Workshops & Schools + +- [Fitting QENS](fitting-qens.ipynb) – A tutorial demonstrating how to + fit a quasielastic neutron scattering (QENS) data using EasyScience + framework. +- [Fitting SANS](fitting-sans.ipynb) – A tutorial demonstrating how to + fit a small-angle neutron scattering (SANS) data using EasyScience + framework. diff --git a/docs/docs/user-guide/index.md b/docs/docs/user-guide/index.md new file mode 100644 index 00000000..bff8e315 --- /dev/null +++ b/docs/docs/user-guide/index.md @@ -0,0 +1,8 @@ +--- +icon: material/book-open-variant +--- + +# :material-book-open-variant: User Guide + +This section is currently under development. Please check back later for +updates. diff --git a/docs/includes/abbreviations.md b/docs/includes/abbreviations.md new file mode 100644 index 00000000..682f16ff --- /dev/null +++ b/docs/includes/abbreviations.md @@ -0,0 +1,15 @@ + + +*[CIF]: Crystallographic Information File. +*[curl]: Command-line tool for transferring data with URLs. +*[GitHub]: A web-based platform for version control and collaboration. +*[Google Colab]: Cloud service that allows you to run Jupyter Notebooks in the cloud. +*[IUCr]: International Union of Crystallography. +*[Jupyter Notebook]: An open-source web application that allows you to create and share documents that contain live code, equations, visualizations, and narrative text. +*[JupyterLab]: Web-based interactive development environment for notebooks, code, and data. +*[pip]: Package installer for Python. +*[PyPI]: The Python Package Index is a repository of software for the Python programming language. +*[Conda]: Conda is a cross-platform, language-agnostic binary package manager. +*[Pixi]: A modern package manager for Windows, macOS, and Linux. + + diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 135acda3..00000000 --- a/docs/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=./src -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% - -:end -popd diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml new file mode 100644 index 00000000..c721c75d --- /dev/null +++ b/docs/mkdocs.yml @@ -0,0 +1,189 @@ +# Project information +site_name: EasyScience Library +site_url: https://easyscience.github.io/core + +# Repository +repo_url: https://github.com/easyscience/core +edit_uri: edit/develop/docs/ + +# Copyright +copyright: © 2021-2026 EasyScience + +# Sets the theme and theme-specific configuration +theme: + name: material + custom_dir: overrides + features: + #- content.action.edit # Temporary disable edit button (until decided on which branch to use and where to host the notebooks) + #- content.action.view + - content.code.annotate + - content.code.copy # Auto generated button to copy a code block's content + - content.tooltips + - navigation.footer + - navigation.indexes + #- navigation.instant # Instant loading, but it causes issues with rendering equations + #- navigation.sections + - navigation.top # Back-to-top button + - navigation.tracking # Anchor tracking + - search.highlight + - search.share + - search.suggest + - toc.follow + palette: + # Palette toggle for light mode + - media: '(prefers-color-scheme: light)' + scheme: default + primary: custom + toggle: + icon: fontawesome/solid/sun + name: Switch to dark mode + # Palette toggle for dark mode + - media: '(prefers-color-scheme: dark)' + scheme: slate + primary: custom + toggle: + icon: fontawesome/solid/moon + name: Switch to light mode + font: + text: Mulish + code: Roboto Mono + icon: + edit: material/file-edit-outline + favicon: assets/images/favicon.png + logo_dark_mode: assets/images/logo_dark.svg + logo_light_mode: assets/images/logo_light.svg + +# A set of key-value pairs, where the values can be any valid YAML +# construct, that will be passed to the template +extra: + generator: false # Disable `Made with Material for MkDocs` (bottom left) + social: # Extra icons in the bottom right corner + - icon: easyscience # File: overrides/.icons/easyscience.svg + link: https://easyscience.org + name: EasyScience Framework Webpage + - icon: easyscience # File: overrides/.icons/easyscience.svg + link: https://easyscience.github.io/corelib + name: EasyScience Main Webpage + - icon: fontawesome/brands/github # Name as in Font Awesome + link: https://github.com/easyscience/core + name: EasyScience Library Source Code on GitHub + # Set custom variables to be used in Markdown and HTML files + vars: + ci_branch: !ENV CI_BRANCH + github_repository: !ENV GITHUB_REPOSITORY + release_version: !ENV RELEASE_VERSION + docs_version: !ENV DOCS_VERSION + notebooks_dir: !ENV NOTEBOOKS_DIR + # Renders a version selector in the header + version: + provider: mike + +# Customization to be included by the theme +extra_css: + - assets/stylesheets/extra.css + +extra_javascript: + - assets/javascripts/extra.js + # MathJax for rendering mathematical expressions + - assets/javascripts/mathjax.js # Custom MathJax config to ensure compatibility with mkdocs-jupyter + - https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js # Official MathJax CDN + +# A list of extensions beyond the ones that MkDocs uses by default (meta, toc, tables, and fenced_code) +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - footnotes + - pymdownx.arithmatex: # rendering of equations and integrates with MathJax or KaTeX + generic: true + - pymdownx.blocks.caption + - pymdownx.details + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + options: + custom_icons: + - docs/overrides/.icons + - pymdownx.highlight: # whether highlighting should be carried out during build time by Pygments + use_pygments: true + pygments_lang_class: true + - pymdownx.snippets: + auto_append: + - docs/includes/abbreviations.md + - pymdownx.superfences: # whether highlighting should be carried out during build time by Pygments + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tabbed: # enables content tabs + alternate_style: true + - pymdownx.tasklist: + custom_checkbox: true + - toc: + toc_depth: 3 + +# A list of plugins (with optional configuration settings) to use when building the site +plugins: + - autorefs + - inline-svg + - markdownextradata # Plugin that injects the mkdocs.yml extra variables into the Markdown template + - mike # Plugin that makes it easy to deploy multiple versions of the docs + - mkdocs-jupyter: + include: ['*.ipynb'] # Default: ['*.py', '*.ipynb'] + execute: false # Do not execute notebooks during build. They are expected to be pre-executed. + allow_errors: false + include_source: true + include_requirejs: true # Required for Plotly + #custom_mathjax_url: 'https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js' # See 'extra_javascript' above + ignore_h1_titles: true # Use titles defined in the nav section below + remove_tag_config: + remove_input_tags: + - hide-in-docs + - mkdocstrings: + handlers: + python: + paths: ['src'] # Change 'src' to your actual sources directory + options: + docstring_style: google + group_by_category: false + heading_level: 1 + show_root_heading: true + show_root_full_path: false + show_submodules: true + show_source: true + - search + +# Determines additional directories to watch when running mkdocs serve +watch: + - includes + - overrides + - ../src + +# Exclude files and folders from the global navigation +not_in_nav: | + index.md + +# Format and layout of the global navigation for the site +nav: + - Introduction: + - Introduction: introduction/index.md + - Installation & Setup: + - Installation & Setup: installation-and-setup/index.md + - User Guide: + - User Guide: user-guide/index.md + - Tutorials: + - Tutorials: tutorials/index.md + - Workshops & Schools: + - Fitting QENS: tutorials/fitting-qens.ipynb + - Fitting SANS: tutorials/fitting-sans.ipynb + - API Reference: + - API Reference: api-reference/index.md + - base_classes: api-reference/base_classes.md + - fitting: api-reference/fitting.md + - global_object: api-reference/global_object.md + - io: api-reference/io.md + - job: api-reference/job.md + - models: api-reference/models.md + - utils: api-reference/utils.md + - variable: api-reference/variable.md diff --git a/docs/overrides/.icons/app.svg b/docs/overrides/.icons/app.svg new file mode 100644 index 00000000..b4fdd4f3 --- /dev/null +++ b/docs/overrides/.icons/app.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/docs/overrides/.icons/easyscience.svg b/docs/overrides/.icons/easyscience.svg new file mode 100644 index 00000000..fb514912 --- /dev/null +++ b/docs/overrides/.icons/easyscience.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/overrides/.icons/google-colab.svg b/docs/overrides/.icons/google-colab.svg new file mode 100644 index 00000000..9cd9d1b0 --- /dev/null +++ b/docs/overrides/.icons/google-colab.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/docs/overrides/main.html b/docs/overrides/main.html new file mode 100644 index 00000000..2e146827 --- /dev/null +++ b/docs/overrides/main.html @@ -0,0 +1,39 @@ +{% extends "base.html" %} + +{% block content %} + +{% if page.nb_url %} + {# Parse notebook path/URL #} + {% set parts = page.nb_url.split('/') %} + {% set tutorial_name = parts[-2] %} + {% set filename = parts[-1] %} + + {# Colab url #} + {% set base_colab_url = "https://colab.research.google.com/github/" %} + {% set colab_url = + base_colab_url ~ config.extra.vars.github_repository ~ + "/blob/gh-pages/" ~ config.extra.vars.docs_version ~ + "/tutorials/" ~ tutorial_name ~ "/" ~ filename + %} + + {# Download link: relative to the current page #} + {% set file_url = filename %} + + {# Open in Colab (absolute GitHub URL; works anywhere) #} + + {% include ".icons/google-colab.svg" %} + + + {# Download: use a RELATIVE link to the file next to this page #} + + {% include ".icons/material/download.svg" %} + +{% endif %} + +{{ super() }} +{% endblock content %} diff --git a/docs/overrides/partials/logo.html b/docs/overrides/partials/logo.html new file mode 100644 index 00000000..78fa69ca --- /dev/null +++ b/docs/overrides/partials/logo.html @@ -0,0 +1,15 @@ +{% if ( config.theme.logo_light_mode and config.theme.logo_dark_mode ) %} +logo +logo +{% elif config.theme.logo %} +logo +{% else %} {% set icon = config.theme.icon.logo or "material/library" %} {% +include ".icons/" ~ icon ~ ".svg" %} {% endif %} diff --git a/docs/src/_static/ec_logo_single.png b/docs/src/_static/ec_logo_single.png deleted file mode 100644 index 77c1f9a4..00000000 Binary files a/docs/src/_static/ec_logo_single.png and /dev/null differ diff --git a/docs/src/_static/ec_sidebar.png b/docs/src/_static/ec_sidebar.png deleted file mode 100644 index a8bb6c7b..00000000 Binary files a/docs/src/_static/ec_sidebar.png and /dev/null differ diff --git a/docs/src/_static/ec_sidebar_w.png b/docs/src/_static/ec_sidebar_w.png deleted file mode 100644 index d1f407a3..00000000 Binary files a/docs/src/_static/ec_sidebar_w.png and /dev/null differ diff --git a/docs/src/_static/favicon.ico b/docs/src/_static/favicon.ico deleted file mode 100644 index 9281805b..00000000 Binary files a/docs/src/_static/favicon.ico and /dev/null differ diff --git a/docs/src/conf.py b/docs/src/conf.py deleted file mode 100644 index f8445631..00000000 --- a/docs/src/conf.py +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/env python - -# SPDX-FileCopyrightText: 2021 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021 Contributors to the EasyScience project - -# -# Configuration file for the Sphinx documentation builder. -# -# This file does only contain a selection of the most common options. For a -# full list see the documentation: -# http://www.sphinx-doc.org/en/master/config - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys -# import toml -from pathlib import Path -import easyscience -# sys.path.insert(0, os.path.abspath('.')) -main_root = Path(__file__).parents[2] -sys.path.append(str(main_root)) - -import datetime - -# project_info = toml.load(os.path.join(main_root, 'pyproject.toml')) - -# -- Project information ----------------------------------------------------- - -project = 'EasyScience' -copyright = f"{datetime.date.today().year}, EasyScience Contributors" -author = "EasyScience Contributors" -# copyright = f"2021, {project_info['tool']['poetry']['authors'][0]}" -# author = project_info['tool']['poetry']['authors'][0] - -# # The short X.Y version -# version = '' -# # The full version, including alpha/beta/rc tags -# release = project_info['tool']['poetry']['version'] -# The short X.Y version. -#version = project_info['project']['version'] -# The full version, including alpha/beta/rc tags. -#version = project_info['project']['version'] -version = easyscience.__version__ - - -intersphinx_mapping = { - 'python': ('https://docs.python.org/3', None), - 'numpy': ('https://numpy.org/doc/stable/', None) -} - -# -- General configuration --------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.githubpages', - 'sphinx.ext.napoleon', - 'sphinx.ext.autodoc', - 'sphinx_autodoc_typehints', - 'sphinx.ext.viewcode', - 'sphinx.ext.mathjax', - 'sphinx.ext.intersphinx', - 'sphinx_gallery.gen_gallery', -] -autoclass_content = 'init' - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = 'en' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' -highlight_language = 'python3' - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'sphinx_book_theme' -html_logo = os.path.join('_static', 'ec_sidebar_w.png') -html_favicon = os.path.join('_static', 'favicon.ico') -html_theme_options = {} -# html_theme_options = { -# 'logo': os.path.join('ec_logo_single.png'), -# 'github_user': project_info['tool']['github']['info']['organization'], -# 'github_repo': project_info['tool']['github']['info']['repo'], -# } - - - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -# html_theme_options = {} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# The default sidebars (for documents that don't match any pattern) are -# defined by theme itself. Builtin themes are using these templates by -# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', -# 'searchbox.html']``. -# -# html_sidebars = {} - - -# -- Options for HTMLHelp output --------------------------------------------- - -# Output file base name for HTML help builder. -htmlhelp_basename = 'easySciencedoc' - - -# -- Options for LaTeX output ------------------------------------------------ - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'EasyScience.tex', 'EasyScience Documentation', - 'Simon Ward', 'manual'), -] - - -# -- Options for manual page output ------------------------------------------ - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'EasyScience', 'EasyScience Documentation', - [author], 1) -] - - -# -- Options for Texinfo output ---------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'EasyScience', 'EasyScience Documentation', - author, 'EasyScience', 'One line description of project.', - 'Miscellaneous'), -] - - -# -- Options for Epub output ------------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = project - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -# -# epub_identifier = '' - -# A unique identification for the text. -# -# epub_uid = '' - -# A list of files that should not be packed into the epub file. -epub_exclude_files = ['search.html'] - - -sphinx_gallery_conf = { - 'examples_dirs': [os.path.join(main_root, 'Examples', 'base'), - os.path.join(main_root, 'Examples', 'fitting')], # path to your example scripts - 'gallery_dirs': ['base_examples', 'fitting_examples'], # path to where to save gallery generated output - 'backreferences_dir': 'gen_modules/backreferences', # directory where function/class granular galleries are stored - # Modules for which function/class level galleries are created. In - # this case sphinx_gallery and numpy in a tuple of strings. - 'doc_module': ('sphinx_gallery', 'numpy', 'EasyScience'), -} \ No newline at end of file diff --git a/docs/src/fitting/introduction.rst b/docs/src/fitting/introduction.rst deleted file mode 100644 index 0a694090..00000000 --- a/docs/src/fitting/introduction.rst +++ /dev/null @@ -1,362 +0,0 @@ -====================== -Fitting in EasyScience -====================== - -EasyScience provides a flexible and powerful fitting framework that supports multiple optimization backends. -This guide covers both basic usage for users wanting to fit their data, and advanced patterns for developers building scientific components. - -Overview --------- - -The EasyScience fitting system consists of: - -* **Parameters**: Scientific values with units, bounds, and fitting capabilities -* **Models**: Objects containing parameters, inheriting from ``ObjBase`` -* **Fitter**: The main fitting engine supporting multiple minimizers -* **Minimizers**: Backend optimization engines (LMFit, Bumps, DFO-LS) - -Quick Start ------------ - -Basic Parameter and Model Setup -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: python - - import numpy as np - from easyscience import ObjBase, Parameter, Fitter - - # Create a simple model with fittable parameters - class SineModel(ObjBase): - def __init__(self, amplitude_val=1.0, frequency_val=1.0, phase_val=0.0): - amplitude = Parameter("amplitude", amplitude_val, min=0, max=10) - frequency = Parameter("frequency", frequency_val, min=0.1, max=5) - phase = Parameter("phase", phase_val, min=-np.pi, max=np.pi) - super().__init__("sine_model", amplitude=amplitude, frequency=frequency, phase=phase) - - def __call__(self, x): - return self.amplitude.value * np.sin(2 * np.pi * self.frequency.value * x + self.phase.value) - -Basic Fitting Example -~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: python - - # Create test data - x_data = np.linspace(0, 2, 100) - true_model = SineModel(amplitude_val=2.5, frequency_val=1.5, phase_val=0.5) - y_data = true_model(x_data) + 0.1 * np.random.normal(size=len(x_data)) - - # Create model to fit with initial guesses - fit_model = SineModel(amplitude_val=1.0, frequency_val=1.0, phase_val=0.0) - - # Set which parameters to fit (unfix them) - fit_model.amplitude.fixed = False - fit_model.frequency.fixed = False - fit_model.phase.fixed = False - - # Create fitter and perform fit - fitter = Fitter(fit_model, fit_model) - result = fitter.fit(x=x_data, y=y_data) - - # Access results - print(f"Chi-squared: {result.chi2}") - print(f"Fitted amplitude: {fit_model.amplitude.value} ± {fit_model.amplitude.error}") - print(f"Fitted frequency: {fit_model.frequency.value} ± {fit_model.frequency.error}") - -Available Minimizers --------------------- - -EasyScience supports multiple optimization backends: - -.. code-block:: python - - from easyscience import AvailableMinimizers - - # View all available minimizers - fitter = Fitter(model, model) - print(fitter.available_minimizers) - # Output: ['LMFit', 'LMFit_leastsq', 'LMFit_powell', 'Bumps', 'Bumps_simplex', 'DFO', 'DFO_leastsq'] - -Switching Minimizers -~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: python - - # Use LMFit (default) - fitter.switch_minimizer(AvailableMinimizers.LMFit) - result1 = fitter.fit(x=x_data, y=y_data) - - # Switch to Bumps - fitter.switch_minimizer(AvailableMinimizers.Bumps) - result2 = fitter.fit(x=x_data, y=y_data) - - # Use DFO for derivative-free optimization - fitter.switch_minimizer(AvailableMinimizers.DFO) - result3 = fitter.fit(x=x_data, y=y_data) - -Parameter Management --------------------- - -Setting Bounds and Constraints -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: python - - # Parameter with bounds - param = Parameter(name="amplitude", value=1.0, min=0.0, max=10.0, unit="m") - - # Fix parameter (exclude from fitting) - param.fixed = True - - # Unfix parameter (include in fitting) - param.fixed = False - - # Change bounds dynamically - param.min = 0.5 - param.max = 8.0 - -Parameter Dependencies -~~~~~~~~~~~~~~~~~~~~~~~ - -Parameters can depend on other parameters through expressions: - -.. code-block:: python - - # Create independent parameters - length = Parameter("length", 10.0, unit="m", min=1, max=100) - width = Parameter("width", 5.0, unit="m", min=1, max=50) - - # Create dependent parameter - area = Parameter.from_dependency( - name="area", - dependency_expression="length * width", - dependency_map={"length": length, "width": width} - ) - - # When length or width changes, area updates automatically - length.value = 15.0 - print(area.value) # Will be 75.0 (15 * 5) - -Using make_dependent_on() Method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can also make an existing parameter dependent on other parameters using the ``make_dependent_on()`` method. This is useful when you want to convert an independent parameter into a dependent one: - -.. code-block:: python - - # Create independent parameters - radius = Parameter("radius", 5.0, unit="m", min=1, max=20) - height = Parameter("height", 10.0, unit="m", min=1, max=50) - volume = Parameter("volume", 100.0, unit="m³") # Initially independent - pi = Parameter("pi", 3.14159, fixed=True) # Constant parameter - - # Make volume dependent on radius and height - volume.make_dependent_on( - dependency_expression="pi * radius**2 * height", - dependency_map={"radius": radius, "height": height, "pi": pi} - ) - - # Now volume automatically updates when radius or height changes - radius.value = 8.0 - print(f"New volume: {volume.value:.2f} m³") # Automatically calculated - - # The parameter becomes dependent and cannot be set directly - try: - volume.value = 200.0 # This will raise an AttributeError - except AttributeError: - print("Cannot set value of dependent parameter directly") - -**What to expect:** - -- The parameter becomes **dependent** and its ``independent`` property becomes ``False`` -- You **cannot directly set** the value, bounds, or variance of a dependent parameter -- The parameter's value is **automatically recalculated** whenever any of its dependencies change -- Dependent parameters **cannot be fitted** (they are automatically fixed) -- The original value, unit, variance, min, and max are **overwritten** by the dependency calculation -- You can **revert to independence** using the ``make_independent()`` method if needed - -Advanced Fitting Options ------------------------- - -Setting Tolerances and Limits -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: python - - fitter = Fitter(model, model) - - # Set convergence tolerance - fitter.tolerance = 1e-8 - - # Limit maximum function evaluations - fitter.max_evaluations = 1000 - - # Perform fit with custom settings - result = fitter.fit(x=x_data, y=y_data) - -Using Weights -~~~~~~~~~~~~~ - -.. code-block:: python - - # Define weights (inverse variance) - weights = 1.0 / errors**2 # where errors are your data uncertainties - - # Fit with weights - result = fitter.fit(x=x_data, y=y_data, weights=weights) - -Multidimensional Fitting -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: python - - class AbsSin2D(ObjBase): - def __init__(self, offset_val=0.0, phase_val=0.0): - offset = Parameter("offset", offset_val) - phase = Parameter("phase", phase_val) - super().__init__("sin2D", offset=offset, phase=phase) - - def __call__(self, x): - X, Y = x[:, 0], x[:, 1] # x is 2D array - return np.abs(np.sin(self.phase.value * X + self.offset.value)) * \ - np.abs(np.sin(self.phase.value * Y + self.offset.value)) - - # Create 2D data - x_2d = np.column_stack([x_grid.ravel(), y_grid.ravel()]) - - # Fit 2D model - model_2d = AbsSin2D(offset_val=0.1, phase_val=1.0) - model_2d.offset.fixed = False - model_2d.phase.fixed = False - - fitter = Fitter(model_2d, model_2d) - result = fitter.fit(x=x_2d, y=z_data.ravel()) - -Accessing Fit Results ---------------------- - -The ``FitResults`` object contains comprehensive information about the fit: - -.. code-block:: python - - result = fitter.fit(x=x_data, y=y_data) - - # Fit statistics - print(f"Chi-squared: {result.chi2}") - print(f"Reduced chi-squared: {result.reduced_chi}") - print(f"Number of parameters: {result.n_pars}") - print(f"Success: {result.success}") - - # Parameter values and uncertainties - for param_name, value in result.p.items(): - error = result.errors.get(param_name, 0.0) - print(f"{param_name}: {value} ± {error}") - - # Calculated values and residuals - y_calculated = result.y_calc - residuals = result.residual - - # Plot results - import matplotlib.pyplot as plt - plt.figure(figsize=(10, 4)) - plt.subplot(121) - plt.plot(x_data, y_data, 'o', label='Data') - plt.plot(x_data, y_calculated, '-', label='Fit') - plt.legend() - plt.subplot(122) - plt.plot(x_data, residuals, 'o') - plt.axhline(0, color='k', linestyle='--') - plt.ylabel('Residuals') - -Developer Guidelines ---------------------- - -Creating Custom Models -~~~~~~~~~~~~~~~~~~~~~~ - -For developers building scientific components: - -.. code-block:: python - - from easyscience import ObjBase, Parameter - - class CustomModel(ObjBase): - def __init__(self, param1_val=1.0, param2_val=0.0): - # Always create Parameters with appropriate bounds and units - param1 = Parameter("param1", param1_val, min=-10, max=10, unit="m/s") - param2 = Parameter("param2", param2_val, min=0, max=1, fixed=True) - - # Call parent constructor with named parameters - super().__init__("custom_model", param1=param1, param2=param2) - - def __call__(self, x): - # Implement your model calculation - return self.param1.value * x + self.param2.value - - def get_fit_parameters(self): - # This is automatically implemented by ObjBase - # Returns only non-fixed parameters - return super().get_fit_parameters() - -Best Practices -~~~~~~~~~~~~~~ - -1. **Always set appropriate bounds** on parameters to constrain the search space -2. **Use meaningful units** for physical parameters -3. **Fix parameters** that shouldn't be optimized -4. **Test with different minimizers** for robustness -5. **Validate results** by checking chi-squared and residuals - -Error Handling -~~~~~~~~~~~~~~ - -.. code-block:: python - - from easyscience.fitting.minimizers import FitError - - try: - result = fitter.fit(x=x_data, y=y_data) - if not result.success: - print(f"Fit failed: {result.message}") - except FitError as e: - print(f"Fitting error: {e}") - except Exception as e: - print(f"Unexpected error: {e}") - -Testing Patterns -~~~~~~~~~~~~~~~~ - -When writing tests for fitting code: - -.. code-block:: python - - import pytest - from easyscience import global_object - - @pytest.fixture - def clear_global_map(): - """Clear global map before each test""" - global_object.map._clear() - yield - global_object.map._clear() - - def test_model_fitting(clear_global_map): - # Create model and test fitting - model = CustomModel() - model.param1.fixed = False - - # Generate test data - x_test = np.linspace(0, 10, 50) - y_test = 2.5 * x_test + 0.1 * np.random.normal(size=len(x_test)) - - # Fit and verify - fitter = Fitter(model, model) - result = fitter.fit(x=x_test, y=y_test) - - assert result.success - assert model.param1.value == pytest.approx(2.5, abs=0.1) - -This comprehensive guide covers the essential aspects of fitting in EasyScience, from basic usage to advanced developer patterns. -The examples are drawn from the actual test suite and demonstrate real-world usage patterns. - diff --git a/docs/src/getting-started/installation.rst b/docs/src/getting-started/installation.rst deleted file mode 100644 index 4d0cef44..00000000 --- a/docs/src/getting-started/installation.rst +++ /dev/null @@ -1,33 +0,0 @@ -************ -Installation -************ - -**EasyScience** requires Python 3.11 or above. - -Install via ``pip`` -------------------- - -The easiest way of obtaining EasyScience and using it in your project is via pip. You can install directly by using: - -.. code-block:: console - - $ pip install EasyScience - -Install as an EasyScience developer ------------------------------------ - -You can obtain the latest development source from our `Github repository -`_.: - -.. code-block:: console - - $ git clone https://github.com/easyscience/corelib - $ cd corelib - -And install via pip: - -.. code-block:: console - - $ pip install -e . - -.. installation-end-content \ No newline at end of file diff --git a/docs/src/getting-started/overview.rst b/docs/src/getting-started/overview.rst deleted file mode 100644 index d5516a1c..00000000 --- a/docs/src/getting-started/overview.rst +++ /dev/null @@ -1,224 +0,0 @@ -.. _overview: - -Overview -======== - -EasyScience is a foundational Python library that provides the building blocks for scientific data simulation, analysis, and fitting. -It implements a descriptor-based object system with global state management, making it easy to create scientific models with parameters -that have units, bounds, and dependencies. - -What is EasyScience? --------------------- - -EasyScience serves as the core foundation for the EasyScience family of projects, offering: - -* **Scientific Parameters**: Values with units, uncertainties, bounds, and fitting capabilities -* **Model Building**: Base classes for creating complex scientific models -* **Multi-backend Fitting**: Support for LMFit, Bumps, and DFO-LS optimization engines -* **Parameter Dependencies**: Express relationships between parameters through mathematical expressions -* **Serialization**: Save and load complete model states including parameter relationships -* **Undo/Redo System**: Track and revert changes to model parameters -* **Global State Management**: Unified tracking of all objects and their relationships - -Key Concepts ------------- - -Descriptor-Based Architecture -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -EasyScience uses a hierarchical descriptor system: - -.. code-block:: python - - from easyscience import Parameter, ObjBase - - # Scientific parameter with units and bounds - temperature = Parameter( - name="temperature", - value=300.0, - unit="K", - min=0, - max=1000, - description="Sample temperature" - ) - - # Model containing parameters - class ThermalModel(ObjBase): - def __init__(self, temp_val=300.0, coeff_val=1.0): - temperature = Parameter("temperature", temp_val, unit="K", min=0, max=1000) - coefficient = Parameter("coefficient", coeff_val, min=0, max=10) - super().__init__("thermal_model", temperature=temperature, coefficient=coefficient) - -The hierarchy flows from: - -* ``DescriptorBase`` → ``DescriptorNumber`` → ``Parameter`` (fittable scientific values) -* ``BasedBase`` → ``ObjBase`` (containers for parameters and scientific models) -* ``CollectionBase`` (mutable sequences of scientific objects) - -Units and Physical Quantities -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -EasyScience integrates with `scipp `_ for robust unit handling: - -.. code-block:: python - - # Parameters automatically handle units - length = Parameter("length", 100, unit="cm", min=0, max=1000) - - # Unit conversions are automatic - length.convert_unit("m") - print(length.value) # 1.0 - print(length.unit) # m - - # Arithmetic operations preserve units - area = length * length # Results in m^2 - -Parameter Dependencies -~~~~~~~~~~~~~~~~~~~~~~~ - -Parameters can depend on other parameters through mathematical expressions: - -.. code-block:: python - - # Independent parameters - radius = Parameter("radius", 5.0, unit="m", min=0, max=100) - height = Parameter("height", 10.0, unit="m", min=0, max=200) - - # Dependent parameter using mathematical expression - volume = Parameter.from_dependency( - name="volume", - dependency_expression="3.14159 * radius**2 * height", - dependency_map={"radius": radius, "height": height} - ) - - # Automatic updates - radius.value = 10.0 - print(volume.value) # Automatically recalculated - -Global State Management -~~~~~~~~~~~~~~~~~~~~~~~ - -All EasyScience objects register with a global map for dependency tracking: - -.. code-block:: python - - from easyscience import global_object - - # All objects are automatically tracked - param = Parameter("test", 1.0) - print(param.unique_name) # Automatically generated unique identifier - - # Access global registry - all_objects = global_object.map.vertices() - - # Clear for testing (important in unit tests) - global_object.map._clear() - -Fitting and Optimization -~~~~~~~~~~~~~~~~~~~~~~~~~ - -EasyScience provides a unified interface to multiple optimization backends: - -.. code-block:: python - - from easyscience import Fitter, AvailableMinimizers - - # Create fitter with model - fitter = Fitter(model, model) # model serves as both object and function - - # Switch between different optimizers - fitter.switch_minimizer(AvailableMinimizers.LMFit) # Levenberg-Marquardt - fitter.switch_minimizer(AvailableMinimizers.Bumps) # Bayesian inference - fitter.switch_minimizer(AvailableMinimizers.DFO) # Derivative-free - - # Perform fit - result = fitter.fit(x=x_data, y=y_data, weights=weights) - -Serialization and Persistence -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Complete model states can be saved and restored: - -.. code-block:: python - - # Save model to dictionary - model_dict = model.as_dict() - - # Save to JSON - import json - with open('model.json', 'w') as f: - json.dump(model_dict, f, indent=2, default=str) - - # Restore model - with open('model.json', 'r') as f: - loaded_dict = json.load(f) - - new_model = Model.from_dict(loaded_dict) - - # Resolve parameter dependencies after loading - from easyscience.variable.parameter_dependency_resolver import resolve_all_parameter_dependencies - resolve_all_parameter_dependencies(new_model) - -Use Cases ---------- - -EasyScience is designed for: - -Scientific Modeling -~~~~~~~~~~~~~~~~~~~~ - -* Creating physics-based models with parameters that have physical meaning -* Handling units consistently throughout calculations -* Managing complex parameter relationships and constraints - -Data Fitting and Analysis -~~~~~~~~~~~~~~~~~~~~~~~~~ - -* Fitting experimental data to theoretical models -* Comparing different optimization algorithms -* Uncertainty quantification and error propagation - -Software Development -~~~~~~~~~~~~~~~~~~~~ - -* Building domain-specific scientific applications -* Creating reusable model components -* Implementing complex scientific workflows - -Research and Education -~~~~~~~~~~~~~~~~~~~~~~ - -* Reproducible scientific computing -* Teaching scientific programming concepts -* Collaborative model development - -Architecture Benefits ---------------------- - -**Type Safety**: Strong typing with unit checking prevents common errors - -**Flexibility**: Multiple optimization backends allow algorithm comparison - -**Extensibility**: Descriptor pattern makes it easy to add new parameter types - -**Reproducibility**: Complete serialization enables exact state restoration - -**Performance**: Efficient observer pattern minimizes unnecessary recalculations - -**Testing**: Global state management with cleanup utilities supports robust testing - -Getting Started ---------------- - -The best way to learn EasyScience is through examples: - -1. **Basic Usage**: Start with simple parameters and models -2. **Fitting Tutorial**: Learn the fitting system with real data -3. **Advanced Features**: Explore parameter dependencies and serialization -4. **Development Guide**: Build your own scientific components - -See the :doc:`installation` guide to get started, then explore the :doc:`../fitting/introduction` for practical examples. - -EasyScience forms the foundation for more specialized packages in the EasyScience ecosystem, providing the core abstractions that make scientific computing more accessible and reliable. - - diff --git a/docs/src/index.rst b/docs/src/index.rst deleted file mode 100644 index 10f795a8..00000000 --- a/docs/src/index.rst +++ /dev/null @@ -1,181 +0,0 @@ -======================================= -Welcome to EasyScience's documentation! -======================================= - -**EasyScience** is a foundational Python library that provides the building blocks for scientific data simulation, analysis, and fitting. -It implements a descriptor-based object system with global state management, making it easier to create scientific models with parameters -that have units, bounds, and dependencies. - -.. code-block:: python - - from easyscience import Parameter, ObjBase, Fitter - - # Create a model with scientific parameters - class SineModel(ObjBase): - def __init__(self, amplitude=1.0, frequency=1.0, phase=0.0): - amp = Parameter("amplitude", amplitude, min=0, max=10, unit="V") - freq = Parameter("frequency", frequency, min=0.1, max=5, unit="Hz") - phase = Parameter("phase", phase, min=-3.14, max=3.14, unit="rad") - super().__init__("sine_model", amplitude=amp, frequency=freq, phase=phase) - - def __call__(self, x): - return self.amplitude.value * np.sin(2*np.pi*self.frequency.value*x + self.phase.value) - - # Fit to experimental data - model = SineModel() - model.amplitude.fixed = False # Allow fitting - fitter = Fitter(model, model) - result = fitter.fit(x=x_data, y=y_data) - -Key Features -============ - -**Scientific Parameters with Units** - Parameters automatically handle physical units, bounds, and uncertainties using `scipp `_ integration. - -**Parameter Dependencies** - Express mathematical relationships between parameters that update automatically when dependencies change. - -**Multi-Backend Fitting** - Unified interface to LMFit, Bumps, and DFO-LS optimization engines with easy algorithm comparison. - -**Complete Serialization** - Save and restore entire model states including parameter relationships and dependencies. - -**Global State Management** - Automatic tracking of all objects and their relationships with built-in undo/redo capabilities. - -**Developer-Friendly** - Clean APIs, comprehensive testing utilities, and extensive documentation for building scientific applications. - -Why EasyScience? -================ - -**Type Safety & Units** - Prevent common scientific computing errors with automatic unit checking and strong typing. - -**Reproducible Research** - Complete state serialization ensures exact reproducibility of scientific analyses. - -**Algorithm Flexibility** - Compare different optimization approaches without changing your model code. - -**Extensible Architecture** - Descriptor pattern makes it easy to create new parameter types and model components. - -Open Source & Cross-Platform -============================ - -EasyScience is free and open-source software with the source code openly shared on `GitHub repository `_. - -* **Cross-platform** - Written in Python and available for Windows, macOS, and Linux -* **Well-tested** - Comprehensive test suite ensuring reliability across platforms -* **Community-driven** - Open to contributions and feature requests -* **Production-ready** - Used in multiple scientific applications worldwide - - -Projects Built with EasyScience -=============================== - -EasyScience serves as the foundation for several scientific applications: - -**easyDiffraction** - .. image:: https://raw.githubusercontent.com/easyScience/easyDiffractionWww/master/assets/img/card.png - :target: https://easydiffraction.org - :width: 300px - - Scientific software for modeling and analysis of neutron diffraction data, providing an intuitive interface for crystallographic refinement. - -**easyReflectometry** - .. image:: https://raw.githubusercontent.com/easyScience/easyReflectometryWww/master/assets/img/card.png - :target: https://easyreflectometry.org - :width: 300px - - Scientific software for modeling and analysis of neutron reflectometry data, enabling detailed study of thin film structures. - -**Your Project Here** - EasyScience's flexible architecture makes it ideal for building domain-specific scientific applications. The comprehensive API and documentation help you get started quickly. - -Quick Start -=========== - -Ready to begin? Here's how to get started: - -1. **Install EasyScience**: ``pip install easyscience`` -2. **Read the Overview**: Understand the core concepts and architecture -3. **Try the Examples**: Work through practical fitting examples -4. **Explore the API**: Dive into the comprehensive reference documentation - -.. code-block:: bash - - pip install easyscience - -Then explore the tutorials and examples to learn the key concepts! - -Documentation Guide -=================== - -.. toctree:: - :caption: Getting Started - :maxdepth: 2 - :titlesonly: - - getting-started/overview - getting-started/installation - -New to EasyScience? Start with the :doc:`getting-started/overview` to understand the core concepts, then follow the :doc:`getting-started/installation` guide. - -.. toctree:: - :caption: User Guides - :maxdepth: 2 - :titlesonly: - - fitting/introduction - -Learn how to use EasyScience for scientific modeling and data fitting with comprehensive examples and best practices. - -.. toctree:: - :caption: API Reference - :maxdepth: 2 - :titlesonly: - - reference/base - -Complete API documentation for all classes, methods, and functions in EasyScience. - -.. toctree:: - :caption: Examples - :maxdepth: 2 - :titlesonly: - - base_examples/index - fitting_examples/index - -Practical examples and tutorials demonstrating real-world usage patterns. - -Need Help? -========== - -* **GitHub Issues**: Report bugs or request features on `GitHub Issues `_ -* **Discussions**: Ask questions in `GitHub Discussions `_ -* **API Reference**: Complete documentation of all classes and methods -* **Examples**: Practical tutorials and code samples - -Contributing -============ - -EasyScience is developed openly and welcomes contributions! Whether you're fixing bugs, adding features, improving documentation, or sharing usage examples, your contributions help make scientific computing more accessible. - -Visit our `GitHub repository `_ to: - -* Report issues or suggest features -* Submit pull requests -* Join discussions about development -* Help improve documentation - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` \ No newline at end of file diff --git a/docs/src/reference/base.rst b/docs/src/reference/base.rst deleted file mode 100644 index 1d91803c..00000000 --- a/docs/src/reference/base.rst +++ /dev/null @@ -1,323 +0,0 @@ -============== -API Reference -============== - -This reference provides detailed documentation for all EasyScience classes and functions. - -Core Variables and Descriptors -============================== - -Descriptor Base Classes ------------------------ - -.. autoclass:: easyscience.variable.DescriptorBase - :members: - :inherited-members: - :show-inheritance: - -.. autoclass:: easyscience.variable.DescriptorNumber - :members: - :inherited-members: - :show-inheritance: - -.. autoclass:: easyscience.variable.DescriptorArray - :members: - :inherited-members: - :show-inheritance: - -.. autoclass:: easyscience.variable.DescriptorStr - :members: - :inherited-members: - :show-inheritance: - -.. autoclass:: easyscience.variable.DescriptorBool - :members: - :inherited-members: - :show-inheritance: - -.. autoclass:: easyscience.variable.DescriptorAnyType - :members: - :inherited-members: - :show-inheritance: - -Parameters ----------- - -.. autoclass:: easyscience.variable.Parameter - :members: - :inherited-members: - :show-inheritance: - - The Parameter class extends DescriptorNumber with fitting capabilities, bounds, and dependency relationships. - - **Key Methods:** - - .. automethod:: from_dependency - :noindex: - .. automethod:: make_dependent_on - :noindex: - .. automethod:: make_independent - :noindex: - .. automethod:: resolve_pending_dependencies - :noindex: - -Base Classes for Models -======================= - -BasedBase ---------- - -.. autoclass:: easyscience.base_classes.BasedBase - :members: - :inherited-members: - :show-inheritance: - - Base class providing serialization, global object registration, and interface management. - -ObjBase -------- - -.. autoclass:: easyscience.base_classes.ObjBase - :members: - :inherited-members: - :show-inheritance: - - Container class for creating scientific models with parameters. All user-defined models should inherit from this class. - - **Key Methods:** - - .. automethod:: get_fit_parameters - :noindex: - .. automethod:: get_parameters - :noindex: - .. automethod:: _add_component - -Collections ------------ - -.. autoclass:: easyscience.base_classes.CollectionBase - :members: - :inherited-members: - :show-inheritance: - - Mutable sequence container for scientific objects with automatic parameter tracking. - -Fitting and Optimization -========================= - -Fitter -------- - -.. autoclass:: easyscience.fitting.Fitter - :members: - :show-inheritance: - - Main fitting engine supporting multiple optimization backends. - - **Key Methods:** - - .. autoproperty:: fit - :noindex: - .. automethod:: switch_minimizer - :noindex: - .. automethod:: make_model - .. automethod:: evaluate - -Available Minimizers --------------------- - -.. autoclass:: easyscience.fitting.AvailableMinimizers - :members: - :show-inheritance: - - Enumeration of available optimization backends. - -Fit Results ------------ - -.. autoclass:: easyscience.fitting.FitResults - :members: - :show-inheritance: - - Container for fitting results including parameters, statistics, and diagnostics. - -Minimizer Base Classes ----------------------- - -.. autoclass:: easyscience.fitting.minimizers.MinimizerBase - :members: - :show-inheritance: - - Abstract base class for all minimizer implementations. - -.. autoclass:: easyscience.fitting.minimizers.LMFit - :members: - :show-inheritance: - - LMFit-based minimizer implementation. - -.. autoclass:: easyscience.fitting.minimizers.Bumps - :members: - :show-inheritance: - - Bumps-based minimizer implementation. - -.. autoclass:: easyscience.fitting.minimizers.DFO - :members: - :show-inheritance: - - DFO-LS-based minimizer implementation. - -Global State Management -======================== - -Global Object -------------- - -.. autoclass:: easyscience.global_object.GlobalObject - :members: - :show-inheritance: - - Singleton managing global state, logging, and object tracking. - -Object Map ----------- - -.. autoclass:: easyscience.global_object.Map - :members: - :show-inheritance: - - Graph-based registry for tracking object relationships and dependencies. - -Undo/Redo System ----------------- - -.. autoclass:: easyscience.global_object.undo_redo.UndoStack - :members: - :show-inheritance: - - Stack-based undo/redo system for parameter changes. - -Serialization and I/O -===================== - -Serializer Components ---------------------- - -.. autoclass:: easyscience.io.SerializerComponent - :members: - :show-inheritance: - - Base class providing serialization capabilities. - -.. autoclass:: easyscience.io.SerializerDict - :members: - :show-inheritance: - - Dictionary-based serialization implementation. - -.. autoclass:: easyscience.io.SerializerBase - :members: - :show-inheritance: - - Base serialization functionality. - -Models and Examples -=================== - -Polynomial Model ----------------- - -.. autoclass:: easyscience.models.Polynomial - :members: - :show-inheritance: - - Built-in polynomial model for demonstration and testing. - -Job Management -============== - -Analysis and Experiments ------------------------- - -.. autoclass:: easyscience.job.AnalysisBase - :members: - :show-inheritance: - -.. autoclass:: easyscience.job.ExperimentBase - :members: - :show-inheritance: - -.. autoclass:: easyscience.job.JobBase - :members: - :show-inheritance: - -.. autoclass:: easyscience.job.TheoreticalModelBase - :members: - :show-inheritance: - -Utility Functions -================= - -Decorators ----------- - -.. autofunction:: easyscience.global_object.undo_redo.property_stack - - Decorator for properties that should be tracked in the undo/redo system. - -Class Tools ------------ - -.. autofunction:: easyscience.utils.classTools.addLoggedProp - - Utility for adding logged properties to classes. - -String Utilities ----------------- - -.. automodule:: easyscience.utils.string - :members: - -Parameter Dependencies ------------------------ - -.. autofunction:: easyscience.variable.parameter_dependency_resolver.resolve_all_parameter_dependencies - - Resolve all pending parameter dependencies after deserialization. - -.. autofunction:: easyscience.variable.parameter_dependency_resolver.get_parameters_with_pending_dependencies - - Find parameters that have unresolved dependencies. - -Constants and Enumerations -=========================== - -.. autodata:: easyscience.global_object - :annotation: GlobalObject - - Global singleton instance managing application state. - -Exception Classes -================= - -.. autoclass:: easyscience.fitting.minimizers.FitError - :show-inheritance: - - Exception raised when fitting operations fail. - -.. autoclass:: scipp.UnitError - :show-inheritance: - - Exception raised for unit-related errors (from scipp dependency). - -Usage Examples -============== - -For practical usage examples and tutorials, see: - -* :doc:`../getting-started/overview` - Introduction and key concepts -* :doc:`../fitting/introduction` - Comprehensive fitting guide -* :doc:`../getting-started/installation` - Installation instructions - -The API reference covers all public classes and methods. For implementation details and advanced usage patterns, refer to the source code and test suites in the repository. diff --git a/Examples/README.rst b/legacy/Examples/README.rst similarity index 100% rename from Examples/README.rst rename to legacy/Examples/README.rst diff --git a/Examples/base/README.rst b/legacy/Examples/base/README.rst similarity index 100% rename from Examples/base/README.rst rename to legacy/Examples/base/README.rst diff --git a/Examples/base/plot_baseclass1.py b/legacy/Examples/base/plot_baseclass1.py similarity index 100% rename from Examples/base/plot_baseclass1.py rename to legacy/Examples/base/plot_baseclass1.py diff --git a/Examples/fitting/README.rst b/legacy/Examples/fitting/README.rst similarity index 100% rename from Examples/fitting/README.rst rename to legacy/Examples/fitting/README.rst diff --git a/PARAMETER_DEPENDENCY_SERIALIZATION.md b/legacy/PARAMETER_DEPENDENCY_SERIALIZATION.md similarity index 73% rename from PARAMETER_DEPENDENCY_SERIALIZATION.md rename to legacy/PARAMETER_DEPENDENCY_SERIALIZATION.md index 82bf0383..66a6659b 100644 --- a/PARAMETER_DEPENDENCY_SERIALIZATION.md +++ b/legacy/PARAMETER_DEPENDENCY_SERIALIZATION.md @@ -1,19 +1,31 @@ # Parameter Dependency Serialization -This document explains how to serialize and deserialize `Parameter` objects that have dependencies. +This document explains how to serialize and deserialize `Parameter` +objects that have dependencies. ## Overview -Parameters with dependencies can now be serialized to dictionaries (and JSON) while preserving their dependency relationships. After deserialization, the dependencies are automatically reconstructed using the `serializer_id` attribute to match parameters, with `unique_name` attribute being used as a fallback. +Parameters with dependencies can now be serialized to dictionaries (and +JSON) while preserving their dependency relationships. After +deserialization, the dependencies are automatically reconstructed using +the `serializer_id` attribute to match parameters, with `unique_name` +attribute being used as a fallback. ## Key Features -- **Automatic dependency serialization**: Dependency expressions and maps are automatically saved during serialization -- **Reliable dependency resolution**: Dependencies are resolved using stable `serializer_id` attributes with `unique_name` as fallback after deserialization -- **Order-independent loading**: Parameters can be loaded in any order thanks to the reliable ID system -- **Bulk dependency resolution**: Utility functions help resolve all dependencies at once -- **JSON compatibility**: Full support for JSON serialization/deserialization -- **Backward compatibility**: Existing code using `unique_name` continues to work as fallback +- **Automatic dependency serialization**: Dependency expressions and + maps are automatically saved during serialization +- **Reliable dependency resolution**: Dependencies are resolved using + stable `serializer_id` attributes with `unique_name` as fallback after + deserialization +- **Order-independent loading**: Parameters can be loaded in any order + thanks to the reliable ID system +- **Bulk dependency resolution**: Utility functions help resolve all + dependencies at once +- **JSON compatibility**: Full support for JSON + serialization/deserialization +- **Backward compatibility**: Existing code using `unique_name` + continues to work as fallback ## Usage @@ -76,7 +88,7 @@ import json param_dict = parameter.as_dict() json_str = json.dumps(param_dict, default=str) -# Deserialize from JSON +# Deserialize from JSON loaded_dict = json.loads(json_str) new_param = Parameter.from_dict(loaded_dict) @@ -111,11 +123,14 @@ resolve_all_parameter_dependencies(new_params) ### Serialization -During serialization, the following additional fields are added to dependent parameters: +During serialization, the following additional fields are added to +dependent parameters: - `_dependency_string`: The original dependency expression -- `_dependency_map_serializer_ids`: A mapping of dependency keys to stable dependency IDs (preferred) -- `_dependency_map_unique_names`: A mapping of dependency keys to unique names (fallback) +- `_dependency_map_serializer_ids`: A mapping of dependency keys to + stable dependency IDs (preferred) +- `_dependency_map_unique_names`: A mapping of dependency keys to unique + names (fallback) - `__serializer_id`: The parameter's own unique dependency ID - `_independent`: Boolean flag indicating if the parameter is dependent @@ -124,21 +139,31 @@ During serialization, the following additional fields are added to dependent par During deserialization: 1. Parameters are created normally but marked as independent temporarily -2. Dependency information is stored in `_pending_dependency_string`, `_pending_dependency_map_serializer_ids`, and `_pending_dependency_map_unique_names` attributes -3. The parameter's own `__serializer_id` is restored from serialized data -4. After all parameters are loaded, `resolve_all_parameter_dependencies()` establishes the dependency relationships using dependency IDs first, then unique names as fallback +2. Dependency information is stored in `_pending_dependency_string`, + `_pending_dependency_map_serializer_ids`, and + `_pending_dependency_map_unique_names` attributes +3. The parameter's own `__serializer_id` is restored from serialized + data +4. After all parameters are loaded, + `resolve_all_parameter_dependencies()` establishes the dependency + relationships using dependency IDs first, then unique names as + fallback ### Dependency Resolution The dependency resolution process: 1. Scans for parameters with pending dependencies -2. First attempts to look up dependency objects by their stable `serializer_id` -3. Falls back to `unique_name` lookup in the global map if serializer_id is not available +2. First attempts to look up dependency objects by their stable + `serializer_id` +3. Falls back to `unique_name` lookup in the global map if serializer_id + is not available 4. Calls `make_dependent_on()` to establish the dependency relationship 5. Cleans up temporary attributes -This dual-strategy approach ensures reliable dependency resolution regardless of parameter loading order while maintaining backward compatibility. +This dual-strategy approach ensures reliable dependency resolution +regardless of parameter loading order while maintaining backward +compatibility. ## Error Handling @@ -152,15 +177,20 @@ The system provides detailed error messages for common issues: ### `resolve_all_parameter_dependencies(obj)` -Recursively finds all Parameter objects with pending dependencies and resolves them. +Recursively finds all Parameter objects with pending dependencies and +resolves them. **Parameters:** -- `obj`: Object to search for Parameters (can be Parameter, list, dict, or complex object) + +- `obj`: Object to search for Parameters (can be Parameter, list, dict, + or complex object) **Returns:** + - None (modifies parameters in place) **Raises:** + - `ValueError`: If dependency resolution fails ### `get_parameters_with_pending_dependencies(obj)` @@ -168,26 +198,37 @@ Recursively finds all Parameter objects with pending dependencies and resolves t Finds all Parameter objects that have pending dependencies. **Parameters:** + - `obj`: Object to search for Parameters **Returns:** + - `List[Parameter]`: List of parameters with pending dependencies ## Best Practices -1. **Always resolve dependencies after deserialization**: Use `resolve_all_parameter_dependencies()` after loading serialized parameters +1. **Always resolve dependencies after deserialization**: Use + `resolve_all_parameter_dependencies()` after loading serialized + parameters -2. **Handle the global map carefully**: The global map must contain all referenced parameters for dependency resolution to work +2. **Handle the global map carefully**: The global map must contain all + referenced parameters for dependency resolution to work -3. **Use unique names for cross-references**: When creating dependency expressions that reference other parameters, consider using unique names with quotes: `'Parameter_0'` +3. **Use unique names for cross-references**: When creating dependency + expressions that reference other parameters, consider using unique + names with quotes: `'Parameter_0'` -4. **Error handling**: Wrap dependency resolution in try-catch blocks for robust error handling +4. **Error handling**: Wrap dependency resolution in try-catch blocks + for robust error handling -5. **Bulk operations**: For complex object hierarchies, use the utility functions to handle all parameters at once +5. **Bulk operations**: For complex object hierarchies, use the utility + functions to handle all parameters at once -6. **Reliable ordering**: With the new dependency ID system, parameters can be loaded in any order without affecting dependency resolution +6. **Reliable ordering**: With the new dependency ID system, parameters + can be loaded in any order without affecting dependency resolution -7. **Access dependency ID**: Use `parameter.serializer_id` to access the stable ID for debugging or manual cross-referencing +7. **Access dependency ID**: Use `parameter.serializer_id` to access the + stable ID for debugging or manual cross-referencing ## Example: Complex Hierarchy @@ -201,16 +242,18 @@ def save_model(model): def load_model(filename): \"\"\"Load a model from JSON and resolve dependencies.\"\"\" global_object.map._clear() # Start fresh - + with open(filename) as f: model_dict = json.load(f) - + model = Model.from_dict(model_dict) - + # Resolve all parameter dependencies resolve_all_parameter_dependencies(model) - + return model ``` -This system ensures that complex parameter hierarchies with dependencies can be reliably serialized and reconstructed while maintaining their behavioral relationships. \ No newline at end of file +This system ensures that complex parameter hierarchies with dependencies +can be reliably serialized and reconstructed while maintaining their +behavioral relationships. diff --git a/examples_old/dataset_examples.ipynb b/legacy/examples_old/dataset_examples.ipynb similarity index 100% rename from examples_old/dataset_examples.ipynb rename to legacy/examples_old/dataset_examples.ipynb diff --git a/examples_old/dimer_example.ipynb b/legacy/examples_old/dimer_example.ipynb similarity index 100% rename from examples_old/dimer_example.ipynb rename to legacy/examples_old/dimer_example.ipynb diff --git a/examples_old/example1.py b/legacy/examples_old/example1.py similarity index 100% rename from examples_old/example1.py rename to legacy/examples_old/example1.py diff --git a/examples_old/example1_dream.py b/legacy/examples_old/example1_dream.py similarity index 100% rename from examples_old/example1_dream.py rename to legacy/examples_old/example1_dream.py diff --git a/examples_old/example2.py b/legacy/examples_old/example2.py similarity index 100% rename from examples_old/example2.py rename to legacy/examples_old/example2.py diff --git a/examples_old/example3.py b/legacy/examples_old/example3.py similarity index 100% rename from examples_old/example3.py rename to legacy/examples_old/example3.py diff --git a/examples_old/example4.py b/legacy/examples_old/example4.py similarity index 100% rename from examples_old/example4.py rename to legacy/examples_old/example4.py diff --git a/examples_old/example5_broken.py b/legacy/examples_old/example5_broken.py similarity index 100% rename from examples_old/example5_broken.py rename to legacy/examples_old/example5_broken.py diff --git a/examples_old/example6_broken.py b/legacy/examples_old/example6_broken.py similarity index 100% rename from examples_old/example6_broken.py rename to legacy/examples_old/example6_broken.py diff --git a/examples_old/example_dataset.py b/legacy/examples_old/example_dataset.py similarity index 100% rename from examples_old/example_dataset.py rename to legacy/examples_old/example_dataset.py diff --git a/examples_old/example_dataset2.py b/legacy/examples_old/example_dataset2.py similarity index 100% rename from examples_old/example_dataset2.py rename to legacy/examples_old/example_dataset2.py diff --git a/examples_old/example_dataset2pt2.py b/legacy/examples_old/example_dataset2pt2.py similarity index 100% rename from examples_old/example_dataset2pt2.py rename to legacy/examples_old/example_dataset2pt2.py diff --git a/examples_old/example_dataset2pt2_broken.py b/legacy/examples_old/example_dataset2pt2_broken.py similarity index 100% rename from examples_old/example_dataset2pt2_broken.py rename to legacy/examples_old/example_dataset2pt2_broken.py diff --git a/examples_old/example_dataset3.py b/legacy/examples_old/example_dataset3.py similarity index 100% rename from examples_old/example_dataset3.py rename to legacy/examples_old/example_dataset3.py diff --git a/examples_old/example_dataset3pt2.py b/legacy/examples_old/example_dataset3pt2.py similarity index 100% rename from examples_old/example_dataset3pt2.py rename to legacy/examples_old/example_dataset3pt2.py diff --git a/examples_old/example_dataset4.py b/legacy/examples_old/example_dataset4.py similarity index 100% rename from examples_old/example_dataset4.py rename to legacy/examples_old/example_dataset4.py diff --git a/examples_old/example_dataset4_2.py b/legacy/examples_old/example_dataset4_2.py similarity index 100% rename from examples_old/example_dataset4_2.py rename to legacy/examples_old/example_dataset4_2.py diff --git a/pixi.lock b/pixi.lock index 00863b1e..5d5f40a6 100644 --- a/pixi.lock +++ b/pixi.lock @@ -5,1289 +5,3200 @@ environments: - url: https://conda.anaconda.org/conda-forge/ indexes: - https://pypi.org/simple + options: + pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-bootstrap_ha15bf96_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.7.0-he4ff34a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/0d/4764669bdf47bd472899b3d3db91fffbe925c8e3038ec591a2fd2ad6a14d/aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/7c/24/75d274228acf35ceeb2850b8ce04de9dd7355ff7a0b49d607ee60c29c518/aiohttp-3.13.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/49/869b49db0bad6fba7c7471d612c356e745929d14e0de63acbc53e88f2a50/dfo_ls-1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6b/be/0f2f4a5e8adc114a02b63d92bf8edbfa24db6fc602fca83c885af2479e0e/editables-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2d/8b/371ab3cec97ee3fe1126b3406b7abd60c8fec8975fd79a3c75cdea0c3d83/fonttools-4.60.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d9/69/4402ea66272dacc10b298cca18ed73e1c0791ff2ae9ed218d3859f9698ac/h5py-3.15.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/04/35/aa8738d6674aba09d3f0c77a1c40aee1dbf10e1b26d03cbd987aa6642e86/hatchling-1.21.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/22/ff/6425bf5c20d79aa5b959d1ce9e65f599632345391381c9a104133fe0b171/matplotlib-3.10.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/0b/9a/c6f79de7ba3a0a8473129936b7b90aa461d3d46fec6f1627672b1dccf4e9/narwhals-2.12.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e7/c3/3031c931098de393393e1f93a38dc9ed6805d86bb801acc3cf2d5bd1e6b7/plotly-6.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/fa/1ef2f8537272a2f383d72b9301c3ef66a49710b3bb7dcb2bd138cf2920d1/python_socketio-5.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/77/34/1956aed61c4abb91926f9513330afac4654cc2a711ecb73085dc4e2e5c1d/scipp-25.11.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/21/f6/4bfb5695d8941e5c570a04d9fcd0d36bce7511b7d78e6e75c8f9791f82d0/scipy-1.16.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/ba/daf16c2d1965bf6237fb696639e3e93645ac6801f7dcaf9ec694a74e9326/setuptools_git_versioning-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: ./ - osx-64: - - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.0-h86bffb9_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.9-h17c18a5_101_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/49/869b49db0bad6fba7c7471d612c356e745929d14e0de63acbc53e88f2a50/dfo_ls-1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6b/be/0f2f4a5e8adc114a02b63d92bf8edbfa24db6fc602fca83c885af2479e0e/editables-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d6/8a/de9cc0540f542963ba5e8f3a1f6ad48fa211badc3177783b9d5cadf79b5d/fonttools-4.60.1-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/b3/40207e0192415cbff7ea1d37b9f24b33f6d38a5a2f5d18a678de78f967ae/h5py-3.15.1-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/04/35/aa8738d6674aba09d3f0c77a1c40aee1dbf10e1b26d03cbd987aa6642e86/hatchling-1.21.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ca/f0/f44f50c9f5b1a1860261092e3bc91ecdc9acda848a8b8c6abfda4a24dd5c/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/02/9c/207547916a02c78f6bdd83448d9b21afbc42f6379ed887ecf610984f3b4e/matplotlib-3.10.7-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6b/31/b46518ecc604d7edf3a4f94cb3bf021fc62aa301f0cb849936968164ef23/msgpack-1.1.2-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/0b/9a/c6f79de7ba3a0a8473129936b7b90aa461d3d46fec6f1627672b1dccf4e9/narwhals-2.12.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e7/c3/3031c931098de393393e1f93a38dc9ed6805d86bb801acc3cf2d5bd1e6b7/plotly-6.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/fa/1ef2f8537272a2f383d72b9301c3ef66a49710b3bb7dcb2bd138cf2920d1/python_socketio-5.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/71/f2/18d5be10ac890ce7490451eb55d41bf9d96e481751362a30ed1a8bc176fa/scipp-25.11.0-cp313-cp313-macosx_11_0_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/72/f1/57e8327ab1508272029e27eeef34f2302ffc156b69e7e233e906c2a5c379/scipy-1.16.3-cp313-cp313-macosx_10_14_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/ba/daf16c2d1965bf6237fb696639e3e93645ac6801f7dcaf9ec694a74e9326/setuptools_git_versioning-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: ./ - osx-arm64: - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.0-h8adb53f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.9-hfc2f54d_101_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/7b/fe0fe0f5e05e13629d893c760465173a15ad0039c0a5b0d0040995c8075e/aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/49/869b49db0bad6fba7c7471d612c356e745929d14e0de63acbc53e88f2a50/dfo_ls-1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6b/be/0f2f4a5e8adc114a02b63d92bf8edbfa24db6fc602fca83c885af2479e0e/editables-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/5b/cdd2c612277b7ac7ec8c0c9bc41812c43dc7b2d5f2b0897e15fdf5a1f915/fonttools-4.60.1-cp313-cp313-macosx_10_13_universal2.whl - - pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/96/ba99a003c763998035b0de4c299598125df5fc6c9ccf834f152ddd60e0fb/h5py-3.15.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/04/35/aa8738d6674aba09d3f0c77a1c40aee1dbf10e1b26d03cbd987aa6642e86/hatchling-1.21.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2d/7a/9d90a151f558e29c3936b8a47ac770235f436f2120aca41a6d5f3d62ae8d/kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/bc/d0/b3d3338d467d3fc937f0bb7f256711395cae6f78e22cef0656159950adf0/matplotlib-3.10.7-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/0b/9a/c6f79de7ba3a0a8473129936b7b90aa461d3d46fec6f1627672b1dccf4e9/narwhals-2.12.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/e7/c3/3031c931098de393393e1f93a38dc9ed6805d86bb801acc3cf2d5bd1e6b7/plotly-6.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/fa/1ef2f8537272a2f383d72b9301c3ef66a49710b3bb7dcb2bd138cf2920d1/python_socketio-5.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/64/7c/d8a343b0a622987335a1ac848084079c47c21e44fcc450f9c145b11a56f6/scipp-25.11.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/44/13/7e63cfba8a7452eb756306aa2fd9b37a29a323b672b964b4fdeded9a3f21/scipy-1.16.3-cp313-cp313-macosx_12_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/ba/daf16c2d1965bf6237fb696639e3e93645ac6801f7dcaf9ec694a74e9326/setuptools_git_versioning-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: ./ - win-64: - - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-h4c7d964_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.0-hf5d6505_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.9-h09917c8_101_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_32.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/49/869b49db0bad6fba7c7471d612c356e745929d14e0de63acbc53e88f2a50/dfo_ls-1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6b/be/0f2f4a5e8adc114a02b63d92bf8edbfa24db6fc602fca83c885af2479e0e/editables-0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/75/4d/b022c1577807ce8b31ffe055306ec13a866f2337ecee96e75b24b9b753ea/fonttools-4.60.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/ea/fbb258a98863f99befb10ed727152b4ae659f322e1d9c0576f8a62754e81/h5py-3.15.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/04/35/aa8738d6674aba09d3f0c77a1c40aee1dbf10e1b26d03cbd987aa6642e86/hatchling-1.21.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/75/bd/f1a5d894000941739f2ae1b65a32892349423ad49c2e6d0771d0bad3fae4/kiwisolver-1.4.9-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/e1/b6/23064a96308b9aeceeffa65e96bcde459a2ea4934d311dee20afde7407a0/matplotlib-3.10.7-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/0b/9a/c6f79de7ba3a0a8473129936b7b90aa461d3d46fec6f1627672b1dccf4e9/narwhals-2.12.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/e7/c3/3031c931098de393393e1f93a38dc9ed6805d86bb801acc3cf2d5bd1e6b7/plotly-6.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/fa/1ef2f8537272a2f383d72b9301c3ef66a49710b3bb7dcb2bd138cf2920d1/python_socketio-5.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f6/f3/9d1bb423a2dc0bbebfc98191095dd410a1268397b9c692d76a3ea971c790/scipp-25.11.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/cd/01/1204382461fcbfeb05b6161b594f4007e78b6eba9b375382f79153172b4d/scipy-1.16.3-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/ba/daf16c2d1965bf6237fb696639e3e93645ac6801f7dcaf9ec694a74e9326/setuptools_git_versioning-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl - - pypi: ./ - dev: - channels: - - url: https://conda.anaconda.org/conda-forge/ - indexes: - - https://pypi.org/simple - packages: - linux-64: - - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-bootstrap_ha15bf96_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - pypi: https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f7/0d/4764669bdf47bd472899b3d3db91fffbe925c8e3038ec591a2fd2ad6a14d/aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/71/c754b1737ad99102e03fa3235acb6cb6d3ac9d6f596cbc3e5f236705abd8/backrefs-6.2-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/46/eb6eca305c77a4489affe1c5d8f4cae82f285d9addd8de4ec084a7184221/cachetools-6.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/45/860a82d618e5c3930faef0a0fe205b752323e5d10ce0c18fe5016fd4f8d2/chardet-7.0.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/02/18785edcdf6266cdd6c6dc7635f1cbeefd9a5b4c3bb8aff8bd681e9dd095/codecov-2.1.13-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/76/b6/67d7c0e1f400b32c883e9342de4a8c2ae7c1a0b57c5de87622b7262e2309/coverage-7.12.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/d0/89247ec250369fc76db477720a26b2fce7ba079ff1380e4ab4529d2fe233/debugpy-1.8.17-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/49/869b49db0bad6fba7c7471d612c356e745929d14e0de63acbc53e88f2a50/dfo_ls-1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a2/e9/90b7d243364d3dce38c8c2a1b8c103d7a8d1383c2b24c735fae0eee038dd/doc8-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6b/be/0f2f4a5e8adc114a02b63d92bf8edbfa24db6fc602fca83c885af2479e0e/editables-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9f/56/13ab06b4f93ca7cac71078fbe37fcea175d3216f31f85c3168a6bbd0bb9a/flake8-7.3.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2d/8b/371ab3cec97ee3fe1126b3406b7abd60c8fec8975fd79a3c75cdea0c3d83/fonttools-4.60.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/4b/d67eedaed19def5967fade3297fed8161b25ba94699efc124b14fb68cdbc/fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d9/69/4402ea66272dacc10b298cca18ed73e1c0791ff2ae9ed218d3859f9698ac/h5py-3.15.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/04/35/aa8738d6674aba09d3f0c77a1c40aee1dbf10e1b26d03cbd987aa6642e86/hatchling-1.21.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/05/aa/62893d6a591d337aa59dcc4c6f6c842f1fe20cd72c8c5c1f980255243252/ipython-9.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/e2/05328bd2621be49a6fed9e3030b1e51a2d04537d3f816d211b9cc53c5262/json5-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6c/1e/5a4d5498eba382fee667ed797cf64ae5d1b13b04356df62f067f48bb0f61/jupyterlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/22/ff/6425bf5c20d79aa5b959d1ce9e65f599632345391381c9a104133fe0b171/matplotlib-3.10.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/0b/9a/c6f79de7ba3a0a8473129936b7b90aa461d3d46fec6f1627672b1dccf4e9/narwhals-2.12.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cc/9a/cd673b2f773a12c992f41309ef81b99da1690426bd2f96957a7ade0d3ed7/nbconvert-7.16.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/83/36557b04cfdc317ed8a525c4993b23e43a8fbcddaddd78619112ca07138c/msgspec-0.20.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/0f/c76bf3dba22c73c38e9b1113b017cf163f7696f50e003404ec5ecdb1e8a6/nh3-0.3.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/04/dc/46066ce18d01645541f0186877377b9371b8fa8017fa8262002b4ef22612/numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/85/ab6d04733a7d6ff32bfc8382bf1b07078228f5d6ebec5266b91bfc5c4ff7/pandas-3.0.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/c3/3031c931098de393393e1f93a38dc9ed6805d86bb801acc3cf2d5bd1e6b7/plotly-6.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/24/538bff45bde96535d7d998c6fed1a751c75ac7c53c37c90dc2601b243893/pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ce/b1/5f49af514f76431ba4eea935b8ad3725cdeb397e9245ab919dbc1d1dc20f/psutil-7.1.3-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/d3/c622950d87a2ffd1654208733b5bd1c5645930014abed8f4c0d74863988b/pydata_sphinx_theme-0.15.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/cc/cecf97be298bee2b2a37dd360618c819a2a7fd95251d8e480c1f0eb88f3b/pyproject_api-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/fa/1ef2f8537272a2f383d72b9301c3ef66a49710b3bb7dcb2bd138cf2920d1/python_socketio-5.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/63/ac52b32b33ae62f2076ed5c4f6b00e065e3ccbb2063e9a2e813b2bfc95bf/restructuredtext_lint-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b9/42/555b4ee17508beafac135c8b450816ace5a96194ce97fefc49d58e5652ea/rpds_py-0.29.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/13/ac/9b9fe63716af8bdfddfacd0882bc1586f29985d3b988b3c62ddce2e202c3/ruff-0.14.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/77/34/1956aed61c4abb91926f9513330afac4654cc2a711ecb73085dc4e2e5c1d/scipp-25.11.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/21/f6/4bfb5695d8941e5c570a04d9fcd0d36bce7511b7d78e6e75c8f9791f82d0/scipy-1.16.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/ba/daf16c2d1965bf6237fb696639e3e93645ac6801f7dcaf9ec694a74e9326/setuptools_git_versioning-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ff/90/bf134f4c1e5243e62690e09d63c55df948a74084c8ac3e48a88468314da6/ruff-0.15.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/94/98/aa2d4b9d28969cc7f62409f9f9fc5b5a853af651255eba03e9bee8546dd9/scipp-25.12.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/05/f2/9657c98a66973b7c35bfd48ba65d1922860de9598fbb535cd96e3f58a908/sphinx_autodoc_typehints-3.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/51/9e/c41d68be04eef5b6202b468e0f90faf0c469f3a03353f2a218fd78279710/sphinx_book_theme-1.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/77/c7/52b48aec16b26c52aba854d03a3a31e0681150301dac1bea2243645a69e7/sphinx_gallery-0.19.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f9/41/fb15f06e33d7430ca89420283a8762a4e6b8025b800ea51796ab5e6d9559/tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fc/cc/e09c0d663a004945f82beecd4f147053567910479314e8d01ba71e5d5dea/tox-4.32.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/9e/8d50f3b3fc4af8c73154f64d4a2293bfa2d517a19000e70ef2d614254084/tox_gh_actions-3.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/50/d4/e51d52047e7eb9a582da59f32125d17c0482d065afd5d3bc435ff2120dc5/tornado-6.5.4-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - pypi: ./ osx-64: - - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.0-h86bffb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libabseil-20260107.1-cxx17_h7ed6875_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.0-h19cb2f5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.9-h17c18a5_101_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/nodejs-25.7.0-hf6efa0e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.12-h894a449_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - pypi: https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl + - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/32/08/de43984c74ed1fca5c014808963cc83cb00d7bb06af228f132d33862ca76/aiohttp-3.13.3-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/71/c754b1737ad99102e03fa3235acb6cb6d3ac9d6f596cbc3e5f236705abd8/backrefs-6.2-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/46/eb6eca305c77a4489affe1c5d8f4cae82f285d9addd8de4ec084a7184221/cachetools-6.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/26/1a22b9a19b4ca167ca462eaf91d0fc31285874d80b0381c55fdc5bc5f066/chardet-7.0.1-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/02/18785edcdf6266cdd6c6dc7635f1cbeefd9a5b4c3bb8aff8bd681e9dd095/codecov-2.1.13-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/b8/14/771700b4048774e48d2c54ed0c674273702713c9ee7acdfede40c2666747/coverage-7.12.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/23/aad45061a31677d68e47499197a131eea55da4875d16c1f42021ab963503/coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/d0/89247ec250369fc76db477720a26b2fce7ba079ff1380e4ab4529d2fe233/debugpy-1.8.17-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/49/869b49db0bad6fba7c7471d612c356e745929d14e0de63acbc53e88f2a50/dfo_ls-1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a2/e9/90b7d243364d3dce38c8c2a1b8c103d7a8d1383c2b24c735fae0eee038dd/doc8-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6b/be/0f2f4a5e8adc114a02b63d92bf8edbfa24db6fc602fca83c885af2479e0e/editables-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9f/56/13ab06b4f93ca7cac71078fbe37fcea175d3216f31f85c3168a6bbd0bb9a/flake8-7.3.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d6/8a/de9cc0540f542963ba5e8f3a1f6ad48fa211badc3177783b9d5cadf79b5d/fonttools-4.60.1-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/ca/468c9a8446a2103ae645d14fee3f610567b7042aba85031c1c65e3ef7471/fonttools-4.61.1-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/b3/40207e0192415cbff7ea1d37b9f24b33f6d38a5a2f5d18a678de78f967ae/h5py-3.15.1-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/04/35/aa8738d6674aba09d3f0c77a1c40aee1dbf10e1b26d03cbd987aa6642e86/hatchling-1.21.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/05/aa/62893d6a591d337aa59dcc4c6f6c842f1fe20cd72c8c5c1f980255243252/ipython-9.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/e2/05328bd2621be49a6fed9e3030b1e51a2d04537d3f816d211b9cc53c5262/json5-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6c/1e/5a4d5498eba382fee667ed797cf64ae5d1b13b04356df62f067f48bb0f61/jupyterlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ca/f0/f44f50c9f5b1a1860261092e3bc91ecdc9acda848a8b8c6abfda4a24dd5c/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/02/9c/207547916a02c78f6bdd83448d9b21afbc42f6379ed887ecf610984f3b4e/matplotlib-3.10.7-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3d/b9/15fd5541ef4f5b9a17eefd379356cf12175fe577424e7b1d80676516031a/matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6b/31/b46518ecc604d7edf3a4f94cb3bf021fc62aa301f0cb849936968164ef23/msgpack-1.1.2-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/0b/9a/c6f79de7ba3a0a8473129936b7b90aa461d3d46fec6f1627672b1dccf4e9/narwhals-2.12.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cc/9a/cd673b2f773a12c992f41309ef81b99da1690426bd2f96957a7ade0d3ed7/nbconvert-7.16.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8a/d1/b902d38b6e5ba3bdddbec469bba388d647f960aeed7b5b3623a8debe8a76/msgspec-0.20.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/75/bc704ae15fee974f8fccd871305e254754167dce5f9e42d88a2def741a1d/multidict-6.7.1-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b6/3e/f5a5cc2885c24be13e9b937441bd16a012ac34a657fe05e58927e8af8b7a/nh3-0.3.2-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a1/22/815b9fe25d1d7ae7d492152adbc7226d3eff731dffc38fe970589fcaaa38/numpy-2.4.2-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0b/48/aad6ec4f8d007534c091e9a7172b3ec1b1ee6d99a9cbb936b5eab6c6cf58/pandas-3.0.1-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/c3/3031c931098de393393e1f93a38dc9ed6805d86bb801acc3cf2d5bd1e6b7/plotly-6.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/14/a1/16c4b823838ba4c9c52c0e6bbda903a3fe5a1bdbf1b8eb4fff7156f3e318/pillow-12.1.1-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ef/94/46b9154a800253e7ecff5aaacdf8ebf43db99de4a2dfa18575b02548654e/psutil-7.1.3-cp36-abi3-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/d3/c622950d87a2ffd1654208733b5bd1c5645930014abed8f4c0d74863988b/pydata_sphinx_theme-0.15.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/cc/cecf97be298bee2b2a37dd360618c819a2a7fd95251d8e480c1f0eb88f3b/pyproject_api-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/fa/1ef2f8537272a2f383d72b9301c3ef66a49710b3bb7dcb2bd138cf2920d1/python_socketio-5.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/63/ac52b32b33ae62f2076ed5c4f6b00e065e3ccbb2063e9a2e813b2bfc95bf/restructuredtext_lint-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/d9/c5de60d9d371bbb186c3e9bf75f4fc5665e11117a25a06a6b2e0afb7380e/rpds_py-0.29.0-cp313-cp313-macosx_10_12_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/36/6a/ad66d0a3315d6327ed6b01f759d83df3c4d5f86c30462121024361137b6a/ruff-0.14.6-py3-none-macosx_10_12_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/71/f2/18d5be10ac890ce7490451eb55d41bf9d96e481751362a30ed1a8bc176fa/scipp-25.11.0-cp313-cp313-macosx_11_0_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/72/f1/57e8327ab1508272029e27eeef34f2302ffc156b69e7e233e906c2a5c379/scipy-1.16.3-cp313-cp313-macosx_10_14_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/ba/daf16c2d1965bf6237fb696639e3e93645ac6801f7dcaf9ec694a74e9326/setuptools_git_versioning-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ce/5d/6a1f271f6e31dffb31855996493641edc3eef8077b883eaf007a2f1c2976/ruff-0.15.4-py3-none-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e5/22/75e119e0a200914f88f121cd956e1eb7f72c8ace4b63171f52ba0334d142/scipp-25.12.0-cp313-cp313-macosx_11_0_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/76/27/07ee1b57b65e92645f219b37148a7e7928b82e2b5dbeccecb4dff7c64f0b/scipy-1.17.1-cp313-cp313-macosx_10_14_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/05/f2/9657c98a66973b7c35bfd48ba65d1922860de9598fbb535cd96e3f58a908/sphinx_autodoc_typehints-3.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/51/9e/c41d68be04eef5b6202b468e0f90faf0c469f3a03353f2a218fd78279710/sphinx_book_theme-1.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/77/c7/52b48aec16b26c52aba854d03a3a31e0681150301dac1bea2243645a69e7/sphinx_gallery-0.19.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f2/b5/9b575a0ed3e50b00c40b08cbce82eb618229091d09f6d14bce80fc01cb0b/tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/fc/cc/e09c0d663a004945f82beecd4f147053567910479314e8d01ba71e5d5dea/tox-4.32.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/9e/8d50f3b3fc4af8c73154f64d4a2293bfa2d517a19000e70ef2d614254084/tox_gh_actions-3.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/db/7e/f7b8d8c4453f305a51f80dbb49014257bb7d28ccb4bbb8dd328ea995ecad/tornado-6.5.4-cp39-abi3-macosx_10_9_x86_64.whl - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - pypi: ./ osx-arm64: - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.0-h8adb53f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.0-h55c6f16_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.9-hfc2f54d_101_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.7.0-hbfc8e16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.12-h20e6be0_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - pypi: https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/7b/fe0fe0f5e05e13629d893c760465173a15ad0039c0a5b0d0040995c8075e/aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/17/f8/8dd2cf6112a5a76f81f81a5130c57ca829d101ad583ce57f889179accdda/aiohttp-3.13.3-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/71/c754b1737ad99102e03fa3235acb6cb6d3ac9d6f596cbc3e5f236705abd8/backrefs-6.2-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/46/eb6eca305c77a4489affe1c5d8f4cae82f285d9addd8de4ec084a7184221/cachetools-6.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/24/fe/2f2425f3b0801e897653723ee827bc87e5a0feacf826ab268a9216680615/chardet-7.0.1-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/02/18785edcdf6266cdd6c6dc7635f1cbeefd9a5b4c3bb8aff8bd681e9dd095/codecov-2.1.13-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/17/a7/3aa4144d3bcb719bf67b22d2d51c2d577bf801498c13cb08f64173e80497/coverage-7.12.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a5/70/9b8b67a0945f3dfec1fd896c5cefb7c19d5a3a6d74630b99a895170999ae/coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b0/d0/89247ec250369fc76db477720a26b2fce7ba079ff1380e4ab4529d2fe233/debugpy-1.8.17-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/49/869b49db0bad6fba7c7471d612c356e745929d14e0de63acbc53e88f2a50/dfo_ls-1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a2/e9/90b7d243364d3dce38c8c2a1b8c103d7a8d1383c2b24c735fae0eee038dd/doc8-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6b/be/0f2f4a5e8adc114a02b63d92bf8edbfa24db6fc602fca83c885af2479e0e/editables-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9f/56/13ab06b4f93ca7cac71078fbe37fcea175d3216f31f85c3168a6bbd0bb9a/flake8-7.3.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7c/5b/cdd2c612277b7ac7ec8c0c9bc41812c43dc7b2d5f2b0897e15fdf5a1f915/fonttools-4.60.1-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4b/cf/00ba28b0990982530addb8dc3e9e6f2fa9cb5c20df2abdda7baa755e8fe1/fonttools-4.61.1-cp313-cp313-macosx_10_13_universal2.whl - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/31/96/ba99a003c763998035b0de4c299598125df5fc6c9ccf834f152ddd60e0fb/h5py-3.15.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/04/35/aa8738d6674aba09d3f0c77a1c40aee1dbf10e1b26d03cbd987aa6642e86/hatchling-1.21.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/05/aa/62893d6a591d337aa59dcc4c6f6c842f1fe20cd72c8c5c1f980255243252/ipython-9.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/e2/05328bd2621be49a6fed9e3030b1e51a2d04537d3f816d211b9cc53c5262/json5-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6c/1e/5a4d5498eba382fee667ed797cf64ae5d1b13b04356df62f067f48bb0f61/jupyterlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2d/7a/9d90a151f558e29c3936b8a47ac770235f436f2120aca41a6d5f3d62ae8d/kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/bc/d0/b3d3338d467d3fc937f0bb7f256711395cae6f78e22cef0656159950adf0/matplotlib-3.10.7-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/8d/a0/2ba3473c1b66b9c74dc7107c67e9008cb1782edbe896d4c899d39ae9cf78/matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/0b/9a/c6f79de7ba3a0a8473129936b7b90aa461d3d46fec6f1627672b1dccf4e9/narwhals-2.12.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cc/9a/cd673b2f773a12c992f41309ef81b99da1690426bd2f96957a7ade0d3ed7/nbconvert-7.16.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/b6/eff0305961a1d9447ec2b02f8c73c8946f22564d302a504185b730c9a761/msgspec-0.20.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b6/3e/f5a5cc2885c24be13e9b937441bd16a012ac34a657fe05e58927e8af8b7a/nh3-0.3.2-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/09/f0/817d03a03f93ba9c6c8993de509277d84e69f9453601915e4a69554102a1/numpy-2.4.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/14/5990826f779f79148ae9d3a2c39593dc04d61d5d90541e71b5749f35af95/pandas-3.0.1-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/c3/3031c931098de393393e1f93a38dc9ed6805d86bb801acc3cf2d5bd1e6b7/plotly-6.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/ad/ad9dc98ff24f485008aa5cdedaf1a219876f6f6c42a4626c08bc4e80b120/pillow-12.1.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/68/3a/9f93cff5c025029a36d9a92fef47220ab4692ee7f2be0fba9f92813d0cb8/psutil-7.1.3-cp36-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/d3/c622950d87a2ffd1654208733b5bd1c5645930014abed8f4c0d74863988b/pydata_sphinx_theme-0.15.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/cc/cecf97be298bee2b2a37dd360618c819a2a7fd95251d8e480c1f0eb88f3b/pyproject_api-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/fa/1ef2f8537272a2f383d72b9301c3ef66a49710b3bb7dcb2bd138cf2920d1/python_socketio-5.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl - - pypi: https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/63/ac52b32b33ae62f2076ed5c4f6b00e065e3ccbb2063e9a2e813b2bfc95bf/restructuredtext_lint-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b3/b3/0860cdd012291dc21272895ce107f1e98e335509ba986dd83d72658b82b9/rpds_py-0.29.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/a3/9d/dae6db96df28e0a15dea8e986ee393af70fc97fd57669808728080529c37/ruff-0.14.6-py3-none-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/64/7c/d8a343b0a622987335a1ac848084079c47c21e44fcc450f9c145b11a56f6/scipp-25.11.0-cp313-cp313-macosx_11_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/44/13/7e63cfba8a7452eb756306aa2fd9b37a29a323b672b964b4fdeded9a3f21/scipy-1.16.3-cp313-cp313-macosx_12_0_arm64.whl - - pypi: https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/ba/daf16c2d1965bf6237fb696639e3e93645ac6801f7dcaf9ec694a74e9326/setuptools_git_versioning-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b1/d8/0fab9f8842b83b1a9c2bf81b85063f65e93fb512e60effa95b0be49bfc54/ruff-0.15.4-py3-none-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/18/5c/bc0ca94bff65fe0d206a369b54625f8ec7852dfd1d835174692026f34df9/scipp-25.12.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ec/ae/db19f8ab842e9b724bf5dbb7db29302a91f1e55bc4d04b1025d6d605a2c5/scipy-1.17.1-cp313-cp313-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/05/f2/9657c98a66973b7c35bfd48ba65d1922860de9598fbb535cd96e3f58a908/sphinx_autodoc_typehints-3.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/51/9e/c41d68be04eef5b6202b468e0f90faf0c469f3a03353f2a218fd78279710/sphinx_book_theme-1.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/77/c7/52b48aec16b26c52aba854d03a3a31e0681150301dac1bea2243645a69e7/sphinx_gallery-0.19.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f6/48/6a7529df2c9cc12efd2e8f5dd219516184d703b34c06786809670df5b3bd/tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl - - pypi: https://files.pythonhosted.org/packages/fc/cc/e09c0d663a004945f82beecd4f147053567910479314e8d01ba71e5d5dea/tox-4.32.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/9e/8d50f3b3fc4af8c73154f64d4a2293bfa2d517a19000e70ef2d614254084/tox_gh_actions-3.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ab/a9/e94a9d5224107d7ce3cc1fab8d5dc97f5ea351ccc6322ee4fb661da94e35/tornado-6.5.4-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - pypi: ./ win-64: - - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-h4c7d964_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.0-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.9-h09917c8_101_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.7.0-h80d1838_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.12-h09917c8_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_32.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda - - pypi: https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/4e/f1/ab0395f8a79933577cdd996dd2f9aa6014af9535f65dddcf88204682fe62/aiohttp-3.13.3-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/71/c754b1737ad99102e03fa3235acb6cb6d3ac9d6f596cbc3e5f236705abd8/backrefs-6.2-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e6/46/eb6eca305c77a4489affe1c5d8f4cae82f285d9addd8de4ec084a7184221/cachetools-6.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ed/44/7acb8f84fc7b5ad3c977ac31865b308881da1c0a6ca58be35554d2473dd7/chardet-7.0.1-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/02/18785edcdf6266cdd6c6dc7635f1cbeefd9a5b4c3bb8aff8bd681e9dd095/codecov-2.1.13-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/91/77/dd4aff9af16ff776bf355a24d87eeb48fc6acde54c907cc1ea89b14a8804/coverage-7.12.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/11/18c79a1cee5ff539a94ec4aa290c1c069a5580fd5cfd2fb2e282f8e905da/debugpy-1.8.17-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/13/f7/a0b368ce54ffff9e9028c098bd2d28cfc5b54f9f6c186929083d4c60ba58/debugpy-1.8.20-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/68/49/869b49db0bad6fba7c7471d612c356e745929d14e0de63acbc53e88f2a50/dfo_ls-1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a2/e9/90b7d243364d3dce38c8c2a1b8c103d7a8d1383c2b24c735fae0eee038dd/doc8-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6b/be/0f2f4a5e8adc114a02b63d92bf8edbfa24db6fc602fca83c885af2479e0e/editables-0.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9f/56/13ab06b4f93ca7cac71078fbe37fcea175d3216f31f85c3168a6bbd0bb9a/flake8-7.3.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/75/4d/b022c1577807ce8b31ffe055306ec13a866f2337ecee96e75b24b9b753ea/fonttools-4.60.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/59/453c06d1d83dc0951b69ef692d6b9f1846680342927df54e9a1ca91c6f90/fonttools-4.61.1-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e5/ea/fbb258a98863f99befb10ed727152b4ae659f322e1d9c0576f8a62754e81/h5py-3.15.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/04/35/aa8738d6674aba09d3f0c77a1c40aee1dbf10e1b26d03cbd987aa6642e86/hatchling-1.21.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/05/aa/62893d6a591d337aa59dcc4c6f6c842f1fe20cd72c8c5c1f980255243252/ipython-9.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/e2/05328bd2621be49a6fed9e3030b1e51a2d04537d3f816d211b9cc53c5262/json5-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6c/1e/5a4d5498eba382fee667ed797cf64ae5d1b13b04356df62f067f48bb0f61/jupyterlab-4.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/75/bd/f1a5d894000941739f2ae1b65a32892349423ad49c2e6d0771d0bad3fae4/kiwisolver-1.4.9-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/e1/b6/23064a96308b9aeceeffa65e96bcde459a2ea4934d311dee20afde7407a0/matplotlib-3.10.7-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/64/40/37612487cc8a437d4dd261b32ca21fe2d79510fe74af74e1f42becb1bdb8/matplotlib-3.10.8-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/0b/9a/c6f79de7ba3a0a8473129936b7b90aa461d3d46fec6f1627672b1dccf4e9/narwhals-2.12.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cc/9a/cd673b2f773a12c992f41309ef81b99da1690426bd2f96957a7ade0d3ed7/nbconvert-7.16.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/25/5e8080fe0117f799b1b68008dc29a65862077296b92550632de015128579/msgspec-0.20.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/64/9a/1a1c154f10a575d20dd634e5697805e589bbdb7673a0ad00e8da90044ba7/nh3-0.3.2-cp38-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/43/bc/6352f343522fcb2c04dbaf94cb30cca6fd32c1a750c06ad6231b4293708c/numpy-2.4.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/7d/216a1588b65a7aa5f4535570418a599d943c85afb1d95b0876fc00aa1468/pandas-3.0.1-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/c3/3031c931098de393393e1f93a38dc9ed6805d86bb801acc3cf2d5bd1e6b7/plotly-6.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/eb/b0834ad8b583d7d9d42b80becff092082a1c3c156bb582590fcc973f1c7c/pillow-12.1.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/55/4c/c3ed1a622b6ae2fd3c945a366e64eb35247a31e4db16cf5095e269e8eb3c/psutil-7.1.3-cp37-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e7/d3/c622950d87a2ffd1654208733b5bd1c5645930014abed8f4c0d74863988b/pydata_sphinx_theme-0.15.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/54/cc/cecf97be298bee2b2a37dd360618c819a2a7fd95251d8e480c1f0eb88f3b/pyproject_api-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cd/fa/1ef2f8537272a2f383d72b9301c3ef66a49710b3bb7dcb2bd138cf2920d1/python_socketio-5.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fc/19/b757fe28008236a4a713e813283721b8a40aa60cd7d3f83549f2e25a3155/pywinpty-3.0.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/e5/cb/58d6ed3fd429c96a90ef01ac9a617af10a6d41469219c25e7dc162abbb71/pywinpty-3.0.3-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/63/ac52b32b33ae62f2076ed5c4f6b00e065e3ccbb2063e9a2e813b2bfc95bf/restructuredtext_lint-2.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/3c/6b/0229d3bed4ddaa409e6d90b0ae967ed4380e4bdd0dad6e59b92c17d42457/rpds_py-0.29.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/fb/02/82240553b77fd1341f80ebb3eaae43ba011c7a91b4224a9f317d8e6591af/ruff-0.14.6-py3-none-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/f6/f3/9d1bb423a2dc0bbebfc98191095dd410a1268397b9c692d76a3ea971c790/scipp-25.11.0-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/cd/01/1204382461fcbfeb05b6161b594f4007e78b6eba9b375382f79153172b4d/scipy-1.16.3-cp313-cp313-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/ba/daf16c2d1965bf6237fb696639e3e93645ac6801f7dcaf9ec694a74e9326/setuptools_git_versioning-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d0/a8/c688ef7e29983976820d18710f955751d9f4d4eb69df658af3d006e2ba3e/ruff-0.15.4-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/eb/d1/b3cd2733a96a36c54c36889b2cfdd0331c1e5b57fa1757485a22d0ec3142/scipp-25.12.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/05/f2/9657c98a66973b7c35bfd48ba65d1922860de9598fbb535cd96e3f58a908/sphinx_autodoc_typehints-3.5.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/51/9e/c41d68be04eef5b6202b468e0f90faf0c469f3a03353f2a218fd78279710/sphinx_book_theme-1.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/77/c7/52b48aec16b26c52aba854d03a3a31e0681150301dac1bea2243645a69e7/sphinx_gallery-0.19.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c7/2a/f609b420c2f564a748a2d80ebfb2ee02a73ca80223af712fca591386cafb/tornado-6.5.2-cp39-abi3-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/fc/cc/e09c0d663a004945f82beecd4f147053567910479314e8d01ba71e5d5dea/tox-4.32.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/fd/9e/8d50f3b3fc4af8c73154f64d4a2293bfa2d517a19000e70ef2d614254084/tox_gh_actions-3.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d6/6d/c69be695a0a64fd37a97db12355a035a6d90f79067a3cf936ec2b1dc38cd/tornado-6.5.4-cp39-abi3-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl - pypi: ./ -packages: -- conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726 - md5: d7c89558ba9fa0495403155b64376d81 - license: None - purls: [] - size: 2562 - timestamp: 1578324546067 -- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - build_number: 16 - sha256: fbe2c5e56a653bebb982eda4876a9178aedfc2b545f25d0ce9c4c0b508253d22 - md5: 73aaf86a425cc6e73fcf236a5a46396d - depends: - - _libgcc_mutex 0.1 conda_forge - - libgomp >=7.5.0 - constrains: - - openmp_impl 9999 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 23621 - timestamp: 1650670423406 -- pypi: https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl - name: accessible-pygments - version: 0.0.5 - sha256: 88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7 - requires_dist: - - pygments>=1.5 - - pillow ; extra == 'dev' - - pkginfo>=1.10 ; extra == 'dev' - - playwright ; extra == 'dev' - - pre-commit ; extra == 'dev' - - setuptools ; extra == 'dev' - - twine>=5.0 ; extra == 'dev' - - hypothesis ; extra == 'tests' - - pytest ; extra == 'tests' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl - name: aiohappyeyeballs - version: 2.6.1 - sha256: f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl - name: aiohttp - version: 3.13.2 - sha256: a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/68/7b/fe0fe0f5e05e13629d893c760465173a15ad0039c0a5b0d0040995c8075e/aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl - name: aiohttp - version: 3.13.2 - sha256: 5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293 - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl - name: aiohttp - version: 3.13.2 - sha256: 088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742 - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f7/0d/4764669bdf47bd472899b3d3db91fffbe925c8e3038ec591a2fd2ad6a14d/aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - name: aiohttp - version: 3.13.2 - sha256: ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e - requires_dist: - - aiohappyeyeballs>=2.5.0 - - aiosignal>=1.4.0 - - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' - - attrs>=17.3.0 - - frozenlist>=1.1.1 - - multidict>=4.5,<7.0 - - propcache>=0.2.0 - - yarl>=1.17.0,<2.0 - - aiodns>=3.3.0 ; extra == 'speedups' - - brotli ; platform_python_implementation == 'CPython' and extra == 'speedups' - - brotlicffi ; platform_python_implementation != 'CPython' and extra == 'speedups' - - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - name: aiosignal - version: 1.4.0 - sha256: 053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e - requires_dist: - - frozenlist>=1.1.0 - - typing-extensions>=4.2 ; python_full_version < '3.13' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl - name: alabaster - version: 1.0.0 - sha256: fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl - name: anyio - version: 4.11.0 - sha256: 0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc - requires_dist: - - exceptiongroup>=1.0.2 ; python_full_version < '3.11' - - idna>=2.8 - - sniffio>=1.1 - - typing-extensions>=4.5 ; python_full_version < '3.13' - - trio>=0.31.0 ; extra == 'trio' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl - name: appnope - version: 0.1.4 - sha256: 502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl - name: argon2-cffi - version: 25.1.0 - sha256: fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741 - requires_dist: - - argon2-cffi-bindings - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl - name: argon2-cffi-bindings - version: 25.1.0 - sha256: d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a - requires_dist: - - cffi>=1.0.1 ; python_full_version < '3.14' - - cffi>=2.0.0b1 ; python_full_version >= '3.14' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl - name: argon2-cffi-bindings - version: 25.1.0 - sha256: 2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44 - requires_dist: - - cffi>=1.0.1 ; python_full_version < '3.14' - - cffi>=2.0.0b1 ; python_full_version >= '3.14' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl - name: argon2-cffi-bindings - version: 25.1.0 - sha256: 7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0 - requires_dist: - - cffi>=1.0.1 ; python_full_version < '3.14' - - cffi>=2.0.0b1 ; python_full_version >= '3.14' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl - name: argon2-cffi-bindings + py-311-env: + channels: + - url: https://conda.anaconda.org/conda-forge/ + indexes: + - https://pypi.org/simple + options: + pypi-prerelease-mode: if-necessary-or-explicit + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.7.0-he4ff34a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a1/7e/6815aab7d3a56610891c76ef79095677b8b5be6646aaf00f69b221765021/aiohttp-3.13.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/f0/35240571e1b67ffb19dafb29ab34150b6f59f93f717b041082cdb1bfceb1/backrefs-6.2-py311-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/9f/3d4ba1650e3eb3e7431a054e3bf1b5eaea25b84c72afabf5ef6fc33305d1/chardet-7.0.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/53/c16972708cbb79f2942922571a687c52bd109a7bd51175aeb7558dff2236/coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/61/1ca198af22f7dd22c17ab86e9024ed3c06299cfdb08170640e9996d501a0/fonttools-4.61.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8b/23/4ab1108e87851ccc69694b03b817d92e142966a6c4abd99e17db77f2c066/h5py-3.15.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/e1/e533435c0be77c3f64040d68d7a657771194a63c279f55573188161e81ca/kiwisolver-1.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8f/a0/7024215e95d456de5883e6732e708d8187d9753a21d32f8ddb3befc0c445/matplotlib-3.10.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/6b/96/5c095b940de3aa6b43a71ec76275ac3537b21bd45c7499b5a17a429110fa/msgspec-0.20.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/5a/56/21b27c560c13822ed93133f08aa6372c53a8e067f11fbed37b4adcdac922/multidict-6.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1b/46/6fa4ea94f1ddf969b2ee941290cca6f1bfac92b53c76ae5f44afe17ceb69/numpy-2.4.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2e/7c/870c7e7daec2a6c7ff2ac9e33b23317230d4e4e954b35112759ea4a924a7/pandas-3.0.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a2/c8/46dfeac5825e600579157eea177be43e2f7ff4a99da9d0d0a49533509ac5/pillow-12.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c8/be/8fed28dd0a180dca19e72c233cbf58efa36df055e5b9d90d64fd1740b828/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/c4/2a6fe5111a01005fc7af3878259ce17684fabb8852815eda6225620f3c59/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f8/1e/372195d326549bb51f0ba0f2ecb9874579906b97e08880e7a65c3bef1a99/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ff/90/bf134f4c1e5243e62690e09d63c55df948a74084c8ac3e48a88468314da6/ruff-0.15.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4e/b6/ffe0bb67cec66cd450acff599bb07507bbf5ffda1a3a15dd2d8dbe7a6da7/scipp-25.12.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/50/d4/e51d52047e7eb9a582da59f32125d17c0482d065afd5d3bc435ff2120dc5/tornado-6.5.4-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: ./ + osx-64: + - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libabseil-20260107.1-cxx17_h7ed6875_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.0-h19cb2f5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/nodejs-25.7.0-hf6efa0e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.11.14-h74c2667_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/82/71/d5c31390d18d4f58115037c432b7e0348c60f6f53b727cad33172144a112/aiohttp-3.13.3-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/f0/35240571e1b67ffb19dafb29ab34150b6f59f93f717b041082cdb1bfceb1/backrefs-6.2-py311-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/00/fb/a90b4510aa9080966c65321db2084bcfa184518ee1ed15570d351649ecb2/chardet-7.0.1-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b4/ad/b59e5b451cf7172b8d1043dc0fa718f23aab379bc1521ee13d4bd9bfa960/coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ac/49/4138d1acb6261499bedde1c07f8c2605d1d8f9d77a151e5507fd3ef084b6/fonttools-4.61.1-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/df/b5/7610b6bd13e4ae77b96ba85abea1c8cb249683217ef09ac9e0ae93f25a91/frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/fd/8349b48b15b47768042cff06ad6e1c229f0a4bd89225bf6b6894fea27e6d/h5py-3.15.1-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/c0/27fe1a68a39cf62472a300e2879ffc13c0538546c359b86f149cc19f6ac3/kiwisolver-1.4.9-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f8/86/de7e3a1cdcfc941483af70609edc06b83e7c8a0e0dc9ac325200a3f4d220/matplotlib-3.10.8-cp311-cp311-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/97/560d11202bcd537abca693fd85d81cebe2107ba17301de42b01ac1677b69/msgpack-1.1.2-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/03/59/fdcb3af72f750a8de2bcf39d62ada70b5eb17b06d7f63860e0a679cb656b/msgspec-0.20.0-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a6/9b/267e64eaf6fc637a15b35f5de31a566634a2740f97d8d094a69d34f524a4/multidict-6.7.1-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d3/44/71852273146957899753e69986246d6a176061ea183407e95418c2aa4d9a/numpy-2.4.2-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ff/07/c7087e003ceee9b9a82539b40414ec557aa795b584a1a346e89180853d79/pandas-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2b/46/5da1ec4a5171ee7bf1a0efa064aba70ba3d6e0788ce3f5acd1375d23c8c0/pillow-12.1.1-cp311-cp311-macosx_10_10_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c2/21/d7b68e911f9c8e18e4ae43bdbc1e1e9bbd971f8866eb81608947b6f585ff/propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e8/72/74a989dd9f2084b3d9530b0915fdda64ac48831c30dbf7c72a41a5232db8/pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/5d/305323ba86b284e6fcb0d842d6adaa2999035f70f8c38a9b6d21ad28c3d4/pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl + - pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/6e/f964e88b3d2abee2a82c1ac8366da848fce1c6d834dc2132c3fda3970290/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ce/5d/6a1f271f6e31dffb31855996493641edc3eef8077b883eaf007a2f1c2976/ruff-0.15.4-py3-none-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/12/0d/3f98a936a30bff4a460b51b9f85c4d994f94249930b2d8bedeb8111a359e/scipp-25.12.0-cp311-cp311-macosx_11_0_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/df/75/b4ce781849931fef6fd529afa6b63711d5a733065722d0c3e2724af9e40a/scipy-1.17.1-cp311-cp311-macosx_10_14_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/db/7e/f7b8d8c4453f305a51f80dbb49014257bb7d28ccb4bbb8dd328ea995ecad/tornado-6.5.4-cp39-abi3-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: ./ + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.0-h55c6f16_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.7.0-hbfc8e16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.14-h18782d2_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/c9/741f8ac91e14b1d2e7100690425a5b2b919a87a5075406582991fb7de920/aiohttp-3.13.3-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/f0/35240571e1b67ffb19dafb29ab34150b6f59f93f717b041082cdb1bfceb1/backrefs-6.2-py311-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/24/fa/3ad0b454a55376b7971fe64c2f225dfe56a491d8d8728fbfba63f8ff416d/chardet-7.0.1-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/17/0cb7ca3de72e5f4ef2ec2fa0089beafbcaaaead1844e8b8a63d35173d77d/coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/12/bf9f4eaa2fad039356cc627587e30ed008c03f1cebd3034376b5ee8d1d44/fonttools-4.61.1-cp311-cp311-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/b0/1c628e26a0b95858f54aba17e1599e7f6cd241727596cc2580b72cb0a9bf/h5py-3.15.1-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/31/a2/a12a503ac1fd4943c50f9822678e8015a790a13b5490354c68afb8489814/kiwisolver-1.4.9-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fd/14/baad3222f424b19ce6ad243c71de1ad9ec6b2e4eb1e458a48fdc6d120401/matplotlib-3.10.8-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/04/28a41024ccbd67467380b6fb440ae916c1e4f25e2cd4c63abe6835ac566e/msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/5a/15/3c225610da9f02505d37d69a77f4a2e7daae2a125f99d638df211ba84e59/msgspec-0.20.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/dd/a4/d45caf2b97b035c57267791ecfaafbd59c68212004b3842830954bb4b02e/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/41/5d17d4058bd0cd96bcbd4d9ff0fb2e21f52702aab9a72e4a594efa18692f/numpy-2.4.2-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/27/90683c7122febeefe84a56f2cde86a9f05f68d53885cebcc473298dfc33e/pandas-3.0.1-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/93/a29e9bc02d1cf557a834da780ceccd54e02421627200696fcf805ebdc3fb/pillow-12.1.1-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/44/37e403fd9455708b3b942949e1d7febc02167662bf1a7da5b78ee1ea2842/pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/5d/305323ba86b284e6fcb0d842d6adaa2999035f70f8c38a9b6d21ad28c3d4/pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl + - pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/ba/24e5ebb7c1c82e74c4e4f33b2112a5573ddc703915b13a073737b59b86e0/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b1/d8/0fab9f8842b83b1a9c2bf81b85063f65e93fb512e60effa95b0be49bfc54/ruff-0.15.4-py3-none-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/6a/3a/ab0eb61593569d5a0d080002e4b8c0998cb1116d8710781b7225c304b880/scipp-25.12.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/f7/58/bccc2861b305abdd1b8663d6130c0b3d7cc22e8d86663edbc8401bfd40d4/scipy-1.17.1-cp311-cp311-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ab/a9/e94a9d5224107d7ce3cc1fab8d5dc97f5ea351ccc6322ee4fb661da94e35/tornado-6.5.4-cp39-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: ./ + win-64: + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.7.0-h80d1838_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.14-h0159041_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/f2/27cdf04c9851712d6c1b99df6821a6623c3c9e55956d4b1e318c337b5a48/aiohttp-3.13.3-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/f0/35240571e1b67ffb19dafb29ab34150b6f59f93f717b041082cdb1bfceb1/backrefs-6.2-py311-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/73/64/9c5c450ba18359a8e8ab2943e6c3a0b100bd394799bc73a844e3c5cd9c7c/chardet-7.0.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/61/08/3d9c8613079d2b11c185b865de9a4c1a68850cfda2b357fae365cf609f29/coverage-7.13.4-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/92/1cb532e88560cbee973396254b21bece8c5d7c2ece958a67afa08c9f10dc/debugpy-1.8.20-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/ad/37dd1ae5fa6e01612a1fbb954f0927681f282925a86e86198ccd7b15d515/fonttools-4.61.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/23/95/499b4e56452ef8b6c95a271af0dde08dac4ddb70515a75f346d4f400579b/h5py-3.15.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/c6/f8df8509fd1eee6c622febe54384a96cfaf4d43bf2ccec7a0cc17e4715c9/kiwisolver-1.4.9-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/6f/d3/a4bbc01c237ab710a1f22b4da72f4ff6d77eb4c7735ea9811a94ae239067/matplotlib-3.10.8-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/89/5e/406b7d578926b68790e390d83a1165a9bfc2d95612a1a9c1c4d5c72ea815/msgspec-0.20.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c9/68/f16a3a8ba6f7b6dc92a1f19669c0810bd2c43fc5a02da13b1cbf8e253845/multidict-6.7.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/76/ae/e0265e0163cf127c24c3969d29f1c4c64551a1e375d95a13d32eab25d364/numpy-2.4.2-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1f/67/af63f83cd6ca603a00fe8530c10a60f0879265b8be00b5930e8e78c5b30b/pandas-3.0.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/31/03/bef822e4f2d8f9d7448c133d0a18185d3cce3e70472774fffefe8b0ed562/pillow-12.1.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/11/66/f14d1d978ea94d1bc21fc98fcf570f9542fe55bfcc40269d4e1a21c19bf7/pydantic_core-2.41.5-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/51/8f/9bb81dd5bb77d22243d33c8397f09377056d5c687aa6d4042bea7fbf8364/pywin32-311-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/79/c3/3e75075c7f71735f22b66fab0481f2c98e3a4d58cba55cb50ba29114bcf6/pywinpty-3.0.3-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/23/6d/d8d92a0eb270a925c9b4dd039c0b4dc10abc2fcbc48331788824ef113935/pyzmq-27.1.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5b/e7b7aa136f28462b344e652ee010d4de26ee9fd16f1bfd5811f5153ccf89/rpds_py-0.30.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d0/a8/c688ef7e29983976820d18710f955751d9f4d4eb69df658af3d006e2ba3e/ruff-0.15.4-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/bd/75/6a3786de6645ac2ccd94fbf83c59cc6b929bfa3a89cb62c8cb3be4de0606/scipp-25.12.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/95/da/0d1df507cf574b3f224ccc3d45244c9a1d732c81dcb26b1e8a766ae271a8/scipy-1.17.1-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d6/6d/c69be695a0a64fd37a97db12355a035a6d90f79067a3cf936ec2b1dc38cd/tornado-6.5.4-cp39-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: ./ + py-313-env: + channels: + - url: https://conda.anaconda.org/conda-forge/ + indexes: + - https://pypi.org/simple + options: + pypi-prerelease-mode: if-necessary-or-explicit + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.7.0-he4ff34a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7c/24/75d274228acf35ceeb2850b8ce04de9dd7355ff7a0b49d607ee60c29c518/aiohttp-3.13.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/71/c754b1737ad99102e03fa3235acb6cb6d3ac9d6f596cbc3e5f236705abd8/backrefs-6.2-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/45/860a82d618e5c3930faef0a0fe205b752323e5d10ce0c18fe5016fd4f8d2/chardet-7.0.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a3/4b/d67eedaed19def5967fade3297fed8161b25ba94699efc124b14fb68cdbc/fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d9/69/4402ea66272dacc10b298cca18ed73e1c0791ff2ae9ed218d3859f9698ac/h5py-3.15.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/28/83/36557b04cfdc317ed8a525c4993b23e43a8fbcddaddd78619112ca07138c/msgspec-0.20.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/dc/46066ce18d01645541f0186877377b9371b8fa8017fa8262002b4ef22612/numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/85/ab6d04733a7d6ff32bfc8382bf1b07078228f5d6ebec5266b91bfc5c4ff7/pandas-3.0.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/24/538bff45bde96535d7d998c6fed1a751c75ac7c53c37c90dc2601b243893/pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ff/90/bf134f4c1e5243e62690e09d63c55df948a74084c8ac3e48a88468314da6/ruff-0.15.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/94/98/aa2d4b9d28969cc7f62409f9f9fc5b5a853af651255eba03e9bee8546dd9/scipp-25.12.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/50/d4/e51d52047e7eb9a582da59f32125d17c0482d065afd5d3bc435ff2120dc5/tornado-6.5.4-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: ./ + osx-64: + - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libabseil-20260107.1-cxx17_h7ed6875_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.0-h19cb2f5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/nodejs-25.7.0-hf6efa0e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.12-h894a449_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/08/de43984c74ed1fca5c014808963cc83cb00d7bb06af228f132d33862ca76/aiohttp-3.13.3-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/71/c754b1737ad99102e03fa3235acb6cb6d3ac9d6f596cbc3e5f236705abd8/backrefs-6.2-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/26/1a22b9a19b4ca167ca462eaf91d0fc31285874d80b0381c55fdc5bc5f066/chardet-7.0.1-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/23/aad45061a31677d68e47499197a131eea55da4875d16c1f42021ab963503/coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/ca/468c9a8446a2103ae645d14fee3f610567b7042aba85031c1c65e3ef7471/fonttools-4.61.1-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b3/40207e0192415cbff7ea1d37b9f24b33f6d38a5a2f5d18a678de78f967ae/h5py-3.15.1-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/f0/f44f50c9f5b1a1860261092e3bc91ecdc9acda848a8b8c6abfda4a24dd5c/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3d/b9/15fd5541ef4f5b9a17eefd379356cf12175fe577424e7b1d80676516031a/matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6b/31/b46518ecc604d7edf3a4f94cb3bf021fc62aa301f0cb849936968164ef23/msgpack-1.1.2-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8a/d1/b902d38b6e5ba3bdddbec469bba388d647f960aeed7b5b3623a8debe8a76/msgspec-0.20.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/75/bc704ae15fee974f8fccd871305e254754167dce5f9e42d88a2def741a1d/multidict-6.7.1-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a1/22/815b9fe25d1d7ae7d492152adbc7226d3eff731dffc38fe970589fcaaa38/numpy-2.4.2-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0b/48/aad6ec4f8d007534c091e9a7172b3ec1b1ee6d99a9cbb936b5eab6c6cf58/pandas-3.0.1-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/14/a1/16c4b823838ba4c9c52c0e6bbda903a3fe5a1bdbf1b8eb4fff7156f3e318/pillow-12.1.1-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl + - pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ce/5d/6a1f271f6e31dffb31855996493641edc3eef8077b883eaf007a2f1c2976/ruff-0.15.4-py3-none-macosx_10_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/e5/22/75e119e0a200914f88f121cd956e1eb7f72c8ace4b63171f52ba0334d142/scipp-25.12.0-cp313-cp313-macosx_11_0_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/76/27/07ee1b57b65e92645f219b37148a7e7928b82e2b5dbeccecb4dff7c64f0b/scipy-1.17.1-cp313-cp313-macosx_10_14_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/db/7e/f7b8d8c4453f305a51f80dbb49014257bb7d28ccb4bbb8dd328ea995ecad/tornado-6.5.4-cp39-abi3-macosx_10_9_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: ./ + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.0-h55c6f16_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.7.0-hbfc8e16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.12-h20e6be0_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/17/f8/8dd2cf6112a5a76f81f81a5130c57ca829d101ad583ce57f889179accdda/aiohttp-3.13.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/71/c754b1737ad99102e03fa3235acb6cb6d3ac9d6f596cbc3e5f236705abd8/backrefs-6.2-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/24/fe/2f2425f3b0801e897653723ee827bc87e5a0feacf826ab268a9216680615/chardet-7.0.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a5/70/9b8b67a0945f3dfec1fd896c5cefb7c19d5a3a6d74630b99a895170999ae/coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4b/cf/00ba28b0990982530addb8dc3e9e6f2fa9cb5c20df2abdda7baa755e8fe1/fonttools-4.61.1-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/31/96/ba99a003c763998035b0de4c299598125df5fc6c9ccf834f152ddd60e0fb/h5py-3.15.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/7a/9d90a151f558e29c3936b8a47ac770235f436f2120aca41a6d5f3d62ae8d/kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/8d/a0/2ba3473c1b66b9c74dc7107c67e9008cb1782edbe896d4c899d39ae9cf78/matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/57/b6/eff0305961a1d9447ec2b02f8c73c8946f22564d302a504185b730c9a761/msgspec-0.20.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/09/f0/817d03a03f93ba9c6c8993de509277d84e69f9453601915e4a69554102a1/numpy-2.4.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/14/5990826f779f79148ae9d3a2c39593dc04d61d5d90541e71b5749f35af95/pandas-3.0.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/ad/ad9dc98ff24f485008aa5cdedaf1a219876f6f6c42a4626c08bc4e80b120/pillow-12.1.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl + - pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/b1/d8/0fab9f8842b83b1a9c2bf81b85063f65e93fb512e60effa95b0be49bfc54/ruff-0.15.4-py3-none-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/18/5c/bc0ca94bff65fe0d206a369b54625f8ec7852dfd1d835174692026f34df9/scipp-25.12.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ec/ae/db19f8ab842e9b724bf5dbb7db29302a91f1e55bc4d04b1025d6d605a2c5/scipy-1.17.1-cp313-cp313-macosx_12_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/ab/a9/e94a9d5224107d7ce3cc1fab8d5dc97f5ea351ccc6322ee4fb661da94e35/tornado-6.5.4-cp39-abi3-macosx_10_9_universal2.whl + - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: ./ + win-64: + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.7.0-h80d1838_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.12-h09917c8_100_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + - pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4e/f1/ab0395f8a79933577cdd996dd2f9aa6014af9535f65dddcf88204682fe62/aiohttp-3.13.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/71/c754b1737ad99102e03fa3235acb6cb6d3ac9d6f596cbc3e5f236705abd8/backrefs-6.2-py313-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cd/3a/577b549de0cc09d95f11087ee63c739bba856cd3952697eec4c4bb91350a/bleach-6.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/8e/278ea79cf8ee0c395a5ad74625b3465c2fc234bb277f171dd59dd203820d/bumps-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ed/44/7acb8f84fc7b5ad3c977ac31865b308881da1c0a6ca58be35554d2473dd7/chardet-7.0.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/f7/a0b368ce54ffff9e9028c098bd2d28cfc5b54f9f6c186929083d4c60ba58/debugpy-1.8.20-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/59/453c06d1d83dc0951b69ef692d6b9f1846680342927df54e9a1ca91c6f90/fonttools-4.61.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e5/ea/fbb258a98863f99befb10ed727152b4ae659f322e1d9c0576f8a62754e81/h5py-3.15.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/75/bd/f1a5d894000941739f2ae1b65a32892349423ad49c2e6d0771d0bad3fae4/kiwisolver-1.4.9-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/64/40/37612487cc8a437d4dd261b32ca21fe2d79510fe74af74e1f42becb1bdb8/matplotlib-3.10.8-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/af/33/ee4519fa02ed11a94aef9559552f3b17bb863f2ecfe1a35dc7f548cde231/matplotlib_inline-0.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/f1/25/5e8080fe0117f799b1b68008dc29a65862077296b92550632de015128579/msgspec-0.20.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/43/bc/6352f343522fcb2c04dbaf94cb30cca6fd32c1a750c06ad6231b4293708c/numpy-2.4.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d6/7d/216a1588b65a7aa5f4535570418a599d943c85afb1d95b0876fc00aa1468/pandas-3.0.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/eb/b0834ad8b583d7d9d42b80becff092082a1c3c156bb582590fcc973f1c7c/pillow-12.1.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/e5/cb/58d6ed3fd429c96a90ef01ac9a617af10a6d41469219c25e7dc162abbb71/pywinpty-3.0.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d0/a8/c688ef7e29983976820d18710f955751d9f4d4eb69df658af3d006e2ba3e/ruff-0.15.4-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/eb/d1/b3cd2733a96a36c54c36889b2cfdd0331c1e5b57fa1757485a22d0ec3142/scipp-25.12.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/d6/6d/c69be695a0a64fd37a97db12355a035a6d90f79067a3cf936ec2b1dc38cd/tornado-6.5.4-cp39-abi3-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + - pypi: ./ +packages: +- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + build_number: 20 + sha256: 1dd3fffd892081df9726d7eb7e0dea6198962ba775bd88842135a4ddb4deb3c9 + md5: a9f577daf3de00bca7c3c76c0ecbd1de + depends: + - __glibc >=2.17,<3.0.a0 + - libgomp >=7.5.0 + constrains: + - openmp_impl <0.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 28948 + timestamp: 1770939786096 +- pypi: https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl + name: aiohappyeyeballs + version: 2.6.1 + sha256: f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/0e/c9/741f8ac91e14b1d2e7100690425a5b2b919a87a5075406582991fb7de920/aiohttp-3.13.3-cp311-cp311-macosx_11_0_arm64.whl + name: aiohttp + version: 3.13.3 + sha256: 28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/17/f8/8dd2cf6112a5a76f81f81a5130c57ca829d101ad583ce57f889179accdda/aiohttp-3.13.3-cp313-cp313-macosx_11_0_arm64.whl + name: aiohttp + version: 3.13.3 + sha256: 425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/32/08/de43984c74ed1fca5c014808963cc83cb00d7bb06af228f132d33862ca76/aiohttp-3.13.3-cp313-cp313-macosx_10_13_x86_64.whl + name: aiohttp + version: 3.13.3 + sha256: 87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/4e/f1/ab0395f8a79933577cdd996dd2f9aa6014af9535f65dddcf88204682fe62/aiohttp-3.13.3-cp313-cp313-win_amd64.whl + name: aiohttp + version: 3.13.3 + sha256: 693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/7c/24/75d274228acf35ceeb2850b8ce04de9dd7355ff7a0b49d607ee60c29c518/aiohttp-3.13.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: aiohttp + version: 3.13.3 + sha256: f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/82/71/d5c31390d18d4f58115037c432b7e0348c60f6f53b727cad33172144a112/aiohttp-3.13.3-cp311-cp311-macosx_10_9_x86_64.whl + name: aiohttp + version: 3.13.3 + sha256: 1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a1/7e/6815aab7d3a56610891c76ef79095677b8b5be6646aaf00f69b221765021/aiohttp-3.13.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: aiohttp + version: 3.13.3 + sha256: 9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/dc/f2/27cdf04c9851712d6c1b99df6821a6623c3c9e55956d4b1e318c337b5a48/aiohttp-3.13.3-cp311-cp311-win_amd64.whl + name: aiohttp + version: 3.13.3 + sha256: 642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f + requires_dist: + - aiohappyeyeballs>=2.5.0 + - aiosignal>=1.4.0 + - async-timeout>=4.0,<6.0 ; python_full_version < '3.11' + - attrs>=17.3.0 + - frozenlist>=1.1.1 + - multidict>=4.5,<7.0 + - propcache>=0.2.0 + - yarl>=1.17.0,<2.0 + - aiodns>=3.3.0 ; extra == 'speedups' + - brotli>=1.2 ; platform_python_implementation == 'CPython' and extra == 'speedups' + - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' + - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and extra == 'speedups' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl + name: aiosignal + version: 1.4.0 + sha256: 053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e + requires_dist: + - frozenlist>=1.1.0 + - typing-extensions>=4.2 ; python_full_version < '3.13' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl + name: annotated-types + version: 0.7.0 + sha256: 1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 + requires_dist: + - typing-extensions>=4.0.0 ; python_full_version < '3.9' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl + name: anyio + version: 4.12.1 + sha256: d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c + requires_dist: + - exceptiongroup>=1.0.2 ; python_full_version < '3.11' + - idna>=2.8 + - typing-extensions>=4.5 ; python_full_version < '3.13' + - trio>=0.32.0 ; python_full_version >= '3.10' and extra == 'trio' + - trio>=0.31.0 ; python_full_version < '3.10' and extra == 'trio' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl + name: appnope + version: 0.1.4 + sha256: 502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c + requires_python: '>=3.6' +- pypi: https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl + name: argon2-cffi + version: 25.1.0 + sha256: fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741 + requires_dist: + - argon2-cffi-bindings + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + name: argon2-cffi-bindings + version: 25.1.0 + sha256: d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a + requires_dist: + - cffi>=1.0.1 ; python_full_version < '3.14' + - cffi>=2.0.0b1 ; python_full_version >= '3.14' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl + name: argon2-cffi-bindings + version: 25.1.0 + sha256: 2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44 + requires_dist: + - cffi>=1.0.1 ; python_full_version < '3.14' + - cffi>=2.0.0b1 ; python_full_version >= '3.14' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl + name: argon2-cffi-bindings + version: 25.1.0 + sha256: 7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0 + requires_dist: + - cffi>=1.0.1 ; python_full_version < '3.14' + - cffi>=2.0.0b1 ; python_full_version >= '3.14' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl + name: argon2-cffi-bindings version: 25.1.0 sha256: a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98 requires_dist: @@ -1315,10 +3226,10 @@ packages: - pytz==2025.2 ; extra == 'test' - simplejson==3.* ; extra == 'test' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl name: asteval - version: 1.0.7 - sha256: d78df08681dfff59031ca624ba7030f9dc576a7a16e2f7a5137c6e7ef3ee60c4 + version: 1.0.8 + sha256: 6c64385c6ff859a474953c124987c7ee8354d781c76509b2c598741c4d1d28e9 requires_dist: - build ; extra == 'dev' - twine ; extra == 'dev' @@ -1339,22 +3250,30 @@ packages: - pytest-cov ; extra == 'test' - pytest-xdist ; extra == 'test' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl name: async-lru - version: 2.0.5 - sha256: ab95404d8d2605310d345932697371a5f40def0487c03d6d0ad9138de52c9943 + version: 2.2.0 + sha256: e2c1cf731eba202b59c5feedaef14ffd9d02ad0037fcda64938699f2c380eafe requires_dist: - typing-extensions>=4.0.0 ; python_full_version < '3.11' - requires_python: '>=3.9' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl name: attrs version: 25.4.0 sha256: adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl + name: autopep8 + version: 2.3.2 + sha256: ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128 + requires_dist: + - pycodestyle>=2.12.0 + - tomli ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl name: babel - version: 2.17.0 - sha256: 4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 + version: 2.18.0 + sha256: e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 requires_dist: - pytz>=2015.7 ; python_full_version < '3.9' - tzdata ; sys_platform == 'win32' and extra == 'dev' @@ -1366,12 +3285,26 @@ packages: - pytz ; extra == 'dev' - setuptools ; extra == 'dev' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/0f/f0/35240571e1b67ffb19dafb29ab34150b6f59f93f717b041082cdb1bfceb1/backrefs-6.2-py311-none-any.whl + name: backrefs + version: '6.2' + sha256: 08aa7fae530c6b2361d7bdcbda1a7c454e330cc9dbcd03f5c23205e430e5c3be + requires_dist: + - regex ; extra == 'extras' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/c5/71/c754b1737ad99102e03fa3235acb6cb6d3ac9d6f596cbc3e5f236705abd8/backrefs-6.2-py313-none-any.whl + name: backrefs + version: '6.2' + sha256: 12df81596ab511f783b7d87c043ce26bc5b0288cf3bb03610fe76b8189282b2b + requires_dist: + - regex ; extra == 'extras' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl name: beautifulsoup4 - version: 4.14.2 - sha256: 5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515 + version: 4.14.3 + sha256: 0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb requires_dist: - - soupsieve>1.2 + - soupsieve>=1.6.1 - typing-extensions>=4.0.0 - cchardet ; extra == 'cchardet' - chardet ; extra == 'chardet' @@ -1397,12 +3330,12 @@ packages: version: 1.9.0 sha256: ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl name: build - version: 1.3.0 - sha256: 7145f0b5061ba90a1500d60bd1b13ca0a8a4cebdd0cc16ed8adf1c0e739f43b4 + version: 1.4.0 + sha256: 6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596 requires_dist: - - packaging>=19.1 + - packaging>=24.0 - pyproject-hooks - colorama ; os_name == 'nt' - importlib-metadata>=4.6 ; python_full_version < '3.10.2' @@ -1440,40 +3373,40 @@ packages: - sphinx ; extra == 'dev' - versioningit ; extra == 'dev' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda - sha256: c30daba32ddebbb7ded490f0e371eae90f51e72db620554089103b4a6934b0d5 - md5: 51a19bba1b8ebfb60df25cde030b7ebc +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 + md5: d2ffd7602c02f2b316fd921d39876885 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 260341 - timestamp: 1757437258798 -- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda - sha256: 8f50b58efb29c710f3cecf2027a8d7325ba769ab10c746eff75cea3ac050b10c - md5: 97c4b3bd8a90722104798175a1bdddbf + size: 260182 + timestamp: 1771350215188 +- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda + sha256: 9f242f13537ef1ce195f93f0cc162965d6cc79da578568d6d8e50f70dd025c42 + md5: 4173ac3b19ec0a4f400b4f782910368b depends: - __osx >=10.13 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 132607 - timestamp: 1757437730085 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda - sha256: b456200636bd5fecb2bec63f7e0985ad2097cf1b83d60ce0b6968dffa6d02aa1 - md5: 58fd217444c2a5701a44244faf518206 + size: 133427 + timestamp: 1771350680709 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + sha256: 540fe54be35fac0c17feefbdc3e29725cce05d7367ffedfaaa1bdda234b019df + md5: 620b85a3f45526a8bc4d23fd78fc22f0 depends: - __osx >=11.0 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 125061 - timestamp: 1757437486465 -- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda - sha256: d882712855624641f48aa9dc3f5feea2ed6b4e6004585d3616386a18186fe692 - md5: 1077e9333c41ff0be8edd1a5ec0ddace + size: 124834 + timestamp: 1771350416561 +- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + sha256: 76dfb71df5e8d1c4eded2dbb5ba15bb8fb2e2b0fe42d94145d5eed4c75c35902 + md5: 4cb8e6b48f67de0b018719cdf1136306 depends: - ucrt >=10.0.20348.0 - vc >=14.3,<15 @@ -1481,36 +3414,69 @@ packages: license: bzip2-1.0.6 license_family: BSD purls: [] - size: 55977 - timestamp: 1757437738856 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-h4c7d964_0.conda - sha256: 686a13bd2d4024fc99a22c1e0e68a7356af3ed3304a8d3ff6bb56249ad4e82f0 - md5: f98fb7db808b94bc1ec5b0e62f9f1069 + size: 56115 + timestamp: 1771350256444 +- conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + sha256: cc9accf72fa028d31c2a038460787751127317dcfa991f8d1f1babf216bb454e + md5: 920bb03579f15389b9e512095ad995b7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 207882 + timestamp: 1765214722852 +- conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda + sha256: 2f5bc0292d595399df0d168355b4e9820affc8036792d6984bd751fdda2bcaea + md5: fc9a153c57c9f070bebaa7eef30a8f17 + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + purls: [] + size: 186122 + timestamp: 1765215100384 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + sha256: 2995f2aed4e53725e5efbc28199b46bf311c3cab2648fc4f10c2227d6d5fa196 + md5: bcb3cba70cf1eec964a03b4ba7775f01 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 180327 + timestamp: 1765215064054 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda + sha256: 37950019c59b99585cee5d30dbc2cc9696ed4e11f5742606a4db1621ed8f94d6 + md5: f001e6e220355b7f87403a4d0e5bf1ca depends: - __win license: ISC purls: [] - size: 152827 - timestamp: 1762967310929 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda - sha256: b986ba796d42c9d3265602bc038f6f5264095702dd546c14bc684e60c385e773 - md5: f0991f0f84902f6b6009b4d2350a83aa + size: 147734 + timestamp: 1772006322223 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + sha256: 67cc7101b36421c5913a1687ef1b99f85b5d6868da3abbf6ec1a4181e79782fc + md5: 4492fd26db29495f0ba23f146cd5638d depends: - __unix license: ISC purls: [] - size: 152432 - timestamp: 1762967197890 -- pypi: https://files.pythonhosted.org/packages/e6/46/eb6eca305c77a4489affe1c5d8f4cae82f285d9addd8de4ec084a7184221/cachetools-6.2.2-py3-none-any.whl - name: cachetools - version: 6.2.2 - sha256: 6c09c98183bf58560c97b2abfcedcbaf6a896a490f534b031b661d3723b45ace - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl + size: 147413 + timestamp: 1772006283803 +- pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl name: certifi - version: 2025.11.12 - sha256: 97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b + version: 2026.2.25 + sha256: 027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl + name: cffi + version: 2.0.0 + sha256: b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe + requires_dist: + - pycparser ; implementation_name != 'PyPy' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl name: cffi version: 2.0.0 @@ -1532,6 +3498,13 @@ packages: requires_dist: - pycparser ; implementation_name != 'PyPy' requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl + name: cffi + version: 2.0.0 + sha256: 2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c + requires_dist: + - pycparser ; implementation_name != 'PyPy' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl name: cffi version: 2.0.0 @@ -1539,10 +3512,74 @@ packages: requires_dist: - pycparser ; implementation_name != 'PyPy' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl + name: cffi + version: 2.0.0 + sha256: 66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5 + requires_dist: + - pycparser ; implementation_name != 'PyPy' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: cffi + version: 2.0.0 + sha256: 8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26 + requires_dist: + - pycparser ; implementation_name != 'PyPy' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl + name: cfgv + version: 3.5.0 + sha256: a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/00/fb/a90b4510aa9080966c65321db2084bcfa184518ee1ed15570d351649ecb2/chardet-7.0.1-cp311-cp311-macosx_10_9_x86_64.whl + name: chardet + version: 7.0.1 + sha256: c3f59dc3e148b54813ec5c7b4b2e025d37f5dc221ee28a06d1a62f169cfaedf5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/24/fa/3ad0b454a55376b7971fe64c2f225dfe56a491d8d8728fbfba63f8ff416d/chardet-7.0.1-cp311-cp311-macosx_11_0_arm64.whl + name: chardet + version: 7.0.1 + sha256: 3355a3c8453d673e7c1664fdd24a0c6ef39964c3d41befc4849250f7eb1de3b5 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/24/fe/2f2425f3b0801e897653723ee827bc87e5a0feacf826ab268a9216680615/chardet-7.0.1-cp313-cp313-macosx_11_0_arm64.whl name: chardet - version: 5.2.0 - sha256: e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970 + version: 7.0.1 + sha256: 63bc210ce73f8a1b87430b949f84d086cb326d67eb259305862e7c8861b73374 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/56/26/1a22b9a19b4ca167ca462eaf91d0fc31285874d80b0381c55fdc5bc5f066/chardet-7.0.1-cp313-cp313-macosx_10_13_x86_64.whl + name: chardet + version: 7.0.1 + sha256: 67fe3f453416ed9343057dcf06583b36aae6d8bdb013370b3ff46bc37b7e30ac + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/73/64/9c5c450ba18359a8e8ab2943e6c3a0b100bd394799bc73a844e3c5cd9c7c/chardet-7.0.1-cp311-cp311-win_amd64.whl + name: chardet + version: 7.0.1 + sha256: 26186f0ea03c4c1f9be20c088b127c71b0e9d487676930fab77625ddec2a4ef2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b9/45/860a82d618e5c3930faef0a0fe205b752323e5d10ce0c18fe5016fd4f8d2/chardet-7.0.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: chardet + version: 7.0.1 + sha256: 8714f0013c208452a98e23595d99cef53c5364565454425f431446eb586e2591 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/e4/9f/3d4ba1650e3eb3e7431a054e3bf1b5eaea25b84c72afabf5ef6fc33305d1/chardet-7.0.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: chardet + version: 7.0.1 + sha256: 265cb3b5dafc0411c0949800a0692f07e986fb663b6ae1ecfba32ad193a55a03 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ed/44/7acb8f84fc7b5ad3c977ac31865b308881da1c0a6ca58be35554d2473dd7/chardet-7.0.1-cp313-cp313-win_amd64.whl + name: chardet + version: 7.0.1 + sha256: c12abc65830068ad05bd257fb953aaaf63a551446688e03e145522086be5738c + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl + name: charset-normalizer + version: 3.4.4 + sha256: 5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: charset-normalizer + version: 3.4.4 + sha256: 840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381 requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl name: charset-normalizer @@ -1554,24 +3591,28 @@ packages: version: 3.4.4 sha256: b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14 requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl + name: charset-normalizer + version: 3.4.4 + sha256: 6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8 + requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: charset-normalizer version: 3.4.4 sha256: a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl + name: click + version: 8.3.1 + sha256: 981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 + requires_dist: + - colorama ; sys_platform == 'win32' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl name: cloudpickle version: 3.1.2 sha256: 9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/af/02/18785edcdf6266cdd6c6dc7635f1cbeefd9a5b4c3bb8aff8bd681e9dd095/codecov-2.1.13-py2.py3-none-any.whl - name: codecov - version: 2.1.13 - sha256: c2ca5e51bba9ebb43644c43d0690148a55086f7f5e6fd36170858fa4206744d5 - requires_dist: - - requests>=2.7.9 - - coverage - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl name: colorama version: 0.4.6 @@ -1584,10 +3625,110 @@ packages: requires_dist: - pytest ; extra == 'test' requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl + name: contourpy + version: 1.3.3 + sha256: 23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381 + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' - pypi: https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl name: contourpy version: 1.3.3 - sha256: 1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263 + sha256: 1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263 + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: contourpy + version: 1.3.3 + sha256: 4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: contourpy + version: 1.3.3 + sha256: 51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db + requires_dist: + - numpy>=1.25 + - furo ; extra == 'docs' + - sphinx>=7.2 ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - bokeh ; extra == 'bokeh' + - selenium ; extra == 'bokeh' + - contourpy[bokeh,docs] ; extra == 'mypy' + - bokeh ; extra == 'mypy' + - docutils-stubs ; extra == 'mypy' + - mypy==1.17.0 ; extra == 'mypy' + - types-pillow ; extra == 'mypy' + - contourpy[test-no-images] ; extra == 'test' + - matplotlib ; extra == 'test' + - pillow ; extra == 'test' + - pytest ; extra == 'test-no-images' + - pytest-cov ; extra == 'test-no-images' + - pytest-rerunfailures ; extra == 'test-no-images' + - pytest-xdist ; extra == 'test-no-images' + - wurlitzer ; extra == 'test-no-images' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl + name: contourpy + version: 1.3.3 + sha256: 177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5 requires_dist: - numpy>=1.25 - furo ; extra == 'docs' @@ -1609,10 +3750,10 @@ packages: - pytest-xdist ; extra == 'test-no-images' - wurlitzer ; extra == 'test-no-images' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl name: contourpy version: 1.3.3 - sha256: 4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 + sha256: 709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1 requires_dist: - numpy>=1.25 - furo ; extra == 'docs' @@ -1634,10 +3775,10 @@ packages: - pytest-xdist ; extra == 'test-no-images' - wurlitzer ; extra == 'test-no-images' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl name: contourpy version: 1.3.3 - sha256: 177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5 + sha256: d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1 requires_dist: - numpy>=1.25 - furo ; extra == 'docs' @@ -1659,10 +3800,10 @@ packages: - pytest-xdist ; extra == 'test-no-images' - wurlitzer ; extra == 'test-no-images' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl name: contourpy version: 1.3.3 - sha256: d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1 + sha256: 3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42 requires_dist: - numpy>=1.25 - furo ; extra == 'docs' @@ -1684,31 +3825,79 @@ packages: - pytest-xdist ; extra == 'test-no-images' - wurlitzer ; extra == 'test-no-images' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/17/a7/3aa4144d3bcb719bf67b22d2d51c2d577bf801498c13cb08f64173e80497/coverage-7.12.0-cp313-cp313-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/9c/22/6d9cfea622a064d17f406bbea1dd37f95ac75094d44e23447df934661add/copier-9.12.0-py3-none-any.whl + name: copier + version: 9.12.0 + sha256: a1bc84dfd2a4b85dbe034999026c0e24ca02a6bc1574f45df07fd76d935c2ea9 + requires_dist: + - colorama>=0.4.6 + - dunamai>=1.7.0 + - funcy>=1.17 + - jinja2-ansible-filters>=1.3.1 + - jinja2>=3.1.5 + - packaging>=23.0 + - pathspec>=0.9.0 + - platformdirs>=4.3.6 + - plumbum>=1.6.9 + - pydantic>=2.4.2 + - pygments>=2.7.1 + - pyyaml>=5.3.1 + - questionary>=1.8.1 + - typing-extensions>=4.0.0,<5.0.0 ; python_full_version < '3.11' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/61/08/3d9c8613079d2b11c185b865de9a4c1a68850cfda2b357fae365cf609f29/coverage-7.13.4-cp311-cp311-win_amd64.whl + name: coverage + version: 7.13.4 + sha256: 2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/76/53/c16972708cbb79f2942922571a687c52bd109a7bd51175aeb7558dff2236/coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + name: coverage + version: 7.13.4 + sha256: 8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7 + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a5/70/9b8b67a0945f3dfec1fd896c5cefb7c19d5a3a6d74630b99a895170999ae/coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl + name: coverage + version: 7.13.4 + sha256: 3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b4/ad/b59e5b451cf7172b8d1043dc0fa718f23aab379bc1521ee13d4bd9bfa960/coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl + name: coverage + version: 7.13.4 + sha256: d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053 + requires_dist: + - tomli ; python_full_version <= '3.11' and extra == 'toml' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/db/23/aad45061a31677d68e47499197a131eea55da4875d16c1f42021ab963503/coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl name: coverage - version: 7.12.0 - sha256: ccf3b2ede91decd2fb53ec73c1f949c3e034129d1e0b07798ff1d02ea0c8fa4a + version: 7.13.4 + sha256: b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9 requires_dist: - tomli ; python_full_version <= '3.11' and extra == 'toml' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/76/b6/67d7c0e1f400b32c883e9342de4a8c2ae7c1a0b57c5de87622b7262e2309/coverage-7.12.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.whl name: coverage - version: 7.12.0 - sha256: bc13baf85cd8a4cfcf4a35c7bc9d795837ad809775f782f697bf630b7e200211 + version: 7.13.4 + sha256: e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd requires_dist: - tomli ; python_full_version <= '3.11' and extra == 'toml' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/91/77/dd4aff9af16ff776bf355a24d87eeb48fc6acde54c907cc1ea89b14a8804/coverage-7.12.0-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl name: coverage - version: 7.12.0 - sha256: ce61969812d6a98a981d147d9ac583a36ac7db7766f2e64a9d4d059c2fe29d07 + version: 7.13.4 + sha256: b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b requires_dist: - tomli ; python_full_version <= '3.11' and extra == 'toml' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b8/14/771700b4048774e48d2c54ed0c674273702713c9ee7acdfede40c2666747/coverage-7.12.0-cp313-cp313-macosx_10_13_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/f1/17/0cb7ca3de72e5f4ef2ec2fa0089beafbcaaaead1844e8b8a63d35173d77d/coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl name: coverage - version: 7.12.0 - sha256: 47324fffca8d8eae7e185b5bb20c14645f23350f870c1649003618ea91a78941 + version: 7.13.4 + sha256: 19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11 requires_dist: - tomli ; python_full_version <= '3.11' and extra == 'toml' requires_python: '>=3.10' @@ -1725,15 +3914,20 @@ packages: - pytest-cov ; extra == 'tests' - pytest-xdist ; extra == 'tests' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/46/11/18c79a1cee5ff539a94ec4aa290c1c069a5580fd5cfd2fb2e282f8e905da/debugpy-1.8.17-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/13/f7/a0b368ce54ffff9e9028c098bd2d28cfc5b54f9f6c186929083d4c60ba58/debugpy-1.8.20-cp313-cp313-win_amd64.whl + name: debugpy + version: 1.8.20 + sha256: eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/d5/92/1cb532e88560cbee973396254b21bece8c5d7c2ece958a67afa08c9f10dc/debugpy-1.8.20-cp311-cp311-win_amd64.whl name: debugpy - version: 1.8.17 - sha256: 6c5cd6f009ad4fca8e33e5238210dc1e5f42db07d4b6ab21ac7ffa904a196420 + version: 1.8.20 + sha256: 1f7650546e0eded1902d0f6af28f787fa1f1dbdbc97ddabaf1cd963a405930cb requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/b0/d0/89247ec250369fc76db477720a26b2fce7ba079ff1380e4ab4529d2fe233/debugpy-1.8.17-py2.py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl name: debugpy - version: 1.8.17 - sha256: 60c7dca6571efe660ccb7a9508d73ca14b8796c4ed484c2002abba714226cfef + version: 1.8.20 + sha256: 5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7 requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl name: decorator @@ -1745,10 +3939,10 @@ packages: version: 0.7.1 sha256: a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' -- pypi: https://files.pythonhosted.org/packages/68/49/869b49db0bad6fba7c7471d612c356e745929d14e0de63acbc53e88f2a50/dfo_ls-1.6-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl name: dfo-ls - version: '1.6' - sha256: 416edce5537237fa417bd27aef5ba91201e856f3daae52ffd44cfacb10f5b771 + version: 1.6.2 + sha256: 961d15e7194f3868e9e48da45010cb6d24d85491007fbee4e38a9f3ab8050cef requires_dist: - setuptools - numpy @@ -1759,71 +3953,95 @@ packages: - sphinx-rtd-theme ; extra == 'dev' - trustregion>=1.1 ; extra == 'trustregion' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl name: dill - version: 0.4.0 - sha256: 44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049 + version: 0.4.1 + sha256: 1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d requires_dist: - objgraph>=1.7.2 ; extra == 'graph' - gprof2dot>=2022.7.29 ; extra == 'profile' - requires_python: '>=3.8' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl name: distlib version: 0.4.0 sha256: 9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 -- pypi: https://files.pythonhosted.org/packages/a2/e9/90b7d243364d3dce38c8c2a1b8c103d7a8d1383c2b24c735fae0eee038dd/doc8-2.0.0-py3-none-any.whl - name: doc8 - version: 2.0.0 - sha256: 9862710027f793c25f9b1899150660e4bf1d4c9a6738742e71f32011e2e3f590 - requires_dist: - - docutils>=0.19,<=0.21.2 - - restructuredtext-lint>=0.7 - - stevedore - - tomli ; python_full_version < '3.11' - - pygments - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl - name: docutils - version: 0.21.2 - sha256: dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 - requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/dc/b4/a7ec1eaee86761a9dbfd339732b4706db3c6b65e970c12f0f56cfcce3dcf/docformatter-1.7.7-py3-none-any.whl + name: docformatter + version: 1.7.7 + sha256: 7af49f8a46346a77858f6651f431b882c503c2f4442c8b4524b920c863277834 + requires_dist: + - charset-normalizer>=3.0.0,<4.0.0 + - tomli>=2.0.0,<3.0.0 ; python_full_version < '3.11' and extra == 'tomli' + - untokenize>=0.1.1,<0.2.0 + requires_python: '>=3.9,<4.0' +- pypi: https://files.pythonhosted.org/packages/87/10/2c7edbf230e5c507d38367af498fa94258ed97205d9b4b6f63a921fe9c49/dunamai-1.26.0-py3-none-any.whl + name: dunamai + version: 1.26.0 + sha256: f584edf0fda0d308cce0961f807bc90a8fe3d9ff4d62f94e72eca7b43f0ed5f6 + requires_dist: + - importlib-metadata>=1.6.0 ; python_full_version < '3.8' + - packaging>=20.9 + requires_python: '>=3.5' - pypi: ./ name: easyscience - version: 2.0.0 - sha256: 3e1433dc7b46ccbb4a5d63a22de63b3113897cd66b602a368db0c08b09b3659c + version: 1.0.1+dev84 + sha256: e259614d3fa62f79e61c5da4d77be6a3479b428b17b850090289b8f306b1856c requires_dist: - asteval - bumps - dfo-ls + - ipykernel + - ipympl + - ipython + - ipywidgets + - jupyterlab - lmfit + - matplotlib - numpy - - scipp + - pixi-kernel + - pooch + - scipp<26.1.0 - uncertainties - - build ; extra == 'build' - - hatchling<=1.21.0 ; extra == 'build' - - setuptools-git-versioning ; extra == 'build' - build ; extra == 'dev' - - codecov ; extra == 'dev' - - flake8 ; extra == 'dev' - - jupyterlab ; extra == 'dev' - - matplotlib ; extra == 'dev' + - copier ; extra == 'dev' + - docformatter ; extra == 'dev' + - gitpython ; extra == 'dev' + - interrogate ; extra == 'dev' + - jinja2 ; extra == 'dev' + - jupyterquiz ; extra == 'dev' + - jupytext ; extra == 'dev' + - mike ; extra == 'dev' + - mkdocs ; extra == 'dev' + - mkdocs-autorefs ; extra == 'dev' + - mkdocs-jupyter ; extra == 'dev' + - mkdocs-markdownextradata-plugin ; extra == 'dev' + - mkdocs-material ; extra == 'dev' + - mkdocs-plugin-inline-svg ; extra == 'dev' + - mkdocstrings-python ; extra == 'dev' + - nbmake ; extra == 'dev' + - nbqa ; extra == 'dev' + - nbstripout ; extra == 'dev' + - pre-commit ; extra == 'dev' - pytest ; extra == 'dev' - pytest-cov ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - pyyaml ; extra == 'dev' + - radon ; extra == 'dev' - ruff ; extra == 'dev' - - tox-gh-actions ; extra == 'dev' - - doc8 ; extra == 'docs' - - readme-renderer ; extra == 'docs' - - sphinx-autodoc-typehints ; extra == 'docs' - - sphinx-book-theme ; extra == 'docs' - - sphinx-gallery ; extra == 'docs' - - toml ; extra == 'docs' + - spdx-headers ; extra == 'dev' + - validate-pyproject[all] ; extra == 'dev' + - versioningit ; extra == 'dev' requires_python: '>=3.11' - editable: true -- pypi: https://files.pythonhosted.org/packages/6b/be/0f2f4a5e8adc114a02b63d92bf8edbfa24db6fc602fca83c885af2479e0e/editables-0.5-py3-none-any.whl - name: editables - version: '0.5' - sha256: 61e5ffa82629e0d8bfe09bc44a07db3c1ab8ed1ce78a6980732870f19b5e7d4c - requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl + name: execnet + version: 2.1.2 + sha256: 67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec + requires_dist: + - hatch ; extra == 'testing' + - pre-commit ; extra == 'testing' + - pytest ; extra == 'testing' + - tox ; extra == 'testing' + requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl name: executing version: 2.2.1 @@ -1850,30 +4068,55 @@ packages: - pytest-benchmark ; extra == 'devel' - pytest-cache ; extra == 'devel' - validictory ; extra == 'devel' -- pypi: https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl name: filelock - version: 3.20.0 - sha256: 339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2 + version: 3.25.0 + sha256: 5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/9f/56/13ab06b4f93ca7cac71078fbe37fcea175d3216f31f85c3168a6bbd0bb9a/flake8-7.3.0-py2.py3-none-any.whl - name: flake8 - version: 7.3.0 - sha256: b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e +- pypi: https://files.pythonhosted.org/packages/07/ad/37dd1ae5fa6e01612a1fbb954f0927681f282925a86e86198ccd7b15d515/fonttools-4.61.1-cp311-cp311-win_amd64.whl + name: fonttools + version: 4.61.1 + sha256: fe2efccb324948a11dd09d22136fe2ac8a97d6c1347cf0b58a911dcd529f66b7 requires_dist: - - mccabe>=0.7.0,<0.8.0 - - pycodestyle>=2.14.0,<2.15.0 - - pyflakes>=3.4.0,<3.5.0 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/2d/8b/371ab3cec97ee3fe1126b3406b7abd60c8fec8975fd79a3c75cdea0c3d83/fonttools-4.60.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/1a/59/453c06d1d83dc0951b69ef692d6b9f1846680342927df54e9a1ca91c6f90/fonttools-4.61.1-cp313-cp313-win_amd64.whl name: fonttools - version: 4.60.1 - sha256: b33a7884fabd72bdf5f910d0cf46be50dce86a0362a65cfc746a4168c67eb96c + version: 4.61.1 + sha256: 21e7c8d76f62ab13c9472ccf74515ca5b9a761d1bde3265152a6dc58700d895b requires_dist: - lxml>=4.0 ; extra == 'lxml' - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' - zopfli>=0.1.4 ; extra == 'woff' - - unicodedata2>=15.1.0 ; python_full_version < '3.13' and extra == 'unicode' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' - lz4>=1.7.4.2 ; extra == 'graphite' - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' @@ -1882,12 +4125,12 @@ packages: - sympy ; extra == 'symfont' - xattr ; sys_platform == 'darwin' and extra == 'type1' - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.23.0 ; extra == 'repacker' + - uharfbuzz>=0.45.0 ; extra == 'repacker' - lxml>=4.0 ; extra == 'all' - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' - zopfli>=0.1.4 ; extra == 'all' - - unicodedata2>=15.1.0 ; python_full_version < '3.13' and extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' - lz4>=1.7.4.2 ; extra == 'all' - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' @@ -1896,18 +4139,18 @@ packages: - sympy ; extra == 'all' - xattr ; sys_platform == 'darwin' and extra == 'all' - skia-pathops>=0.5.0 ; extra == 'all' - - uharfbuzz>=0.23.0 ; extra == 'all' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/75/4d/b022c1577807ce8b31ffe055306ec13a866f2337ecee96e75b24b9b753ea/fonttools-4.60.1-cp313-cp313-win_amd64.whl + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/4b/cf/00ba28b0990982530addb8dc3e9e6f2fa9cb5c20df2abdda7baa755e8fe1/fonttools-4.61.1-cp313-cp313-macosx_10_13_universal2.whl name: fonttools - version: 4.60.1 - sha256: a3db56f153bd4c5c2b619ab02c5db5192e222150ce5a1bc10f16164714bc39ac + version: 4.61.1 + sha256: 8c56c488ab471628ff3bfa80964372fc13504ece601e0d97a78ee74126b2045c requires_dist: - lxml>=4.0 ; extra == 'lxml' - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' - zopfli>=0.1.4 ; extra == 'woff' - - unicodedata2>=15.1.0 ; python_full_version < '3.13' and extra == 'unicode' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' - lz4>=1.7.4.2 ; extra == 'graphite' - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' @@ -1916,12 +4159,12 @@ packages: - sympy ; extra == 'symfont' - xattr ; sys_platform == 'darwin' and extra == 'type1' - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.23.0 ; extra == 'repacker' + - uharfbuzz>=0.45.0 ; extra == 'repacker' - lxml>=4.0 ; extra == 'all' - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' - zopfli>=0.1.4 ; extra == 'all' - - unicodedata2>=15.1.0 ; python_full_version < '3.13' and extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' - lz4>=1.7.4.2 ; extra == 'all' - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' @@ -1930,18 +4173,18 @@ packages: - sympy ; extra == 'all' - xattr ; sys_platform == 'darwin' and extra == 'all' - skia-pathops>=0.5.0 ; extra == 'all' - - uharfbuzz>=0.23.0 ; extra == 'all' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/7c/5b/cdd2c612277b7ac7ec8c0c9bc41812c43dc7b2d5f2b0897e15fdf5a1f915/fonttools-4.60.1-cp313-cp313-macosx_10_13_universal2.whl + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/5a/ca/468c9a8446a2103ae645d14fee3f610567b7042aba85031c1c65e3ef7471/fonttools-4.61.1-cp313-cp313-macosx_10_13_x86_64.whl name: fonttools - version: 4.60.1 - sha256: 6f68576bb4bbf6060c7ab047b1574a1ebe5c50a17de62830079967b211059ebb + version: 4.61.1 + sha256: dc492779501fa723b04d0ab1f5be046797fee17d27700476edc7ee9ae535a61e requires_dist: - lxml>=4.0 ; extra == 'lxml' - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' - zopfli>=0.1.4 ; extra == 'woff' - - unicodedata2>=15.1.0 ; python_full_version < '3.13' and extra == 'unicode' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' - lz4>=1.7.4.2 ; extra == 'graphite' - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' @@ -1950,12 +4193,12 @@ packages: - sympy ; extra == 'symfont' - xattr ; sys_platform == 'darwin' and extra == 'type1' - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.23.0 ; extra == 'repacker' + - uharfbuzz>=0.45.0 ; extra == 'repacker' - lxml>=4.0 ; extra == 'all' - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' - zopfli>=0.1.4 ; extra == 'all' - - unicodedata2>=15.1.0 ; python_full_version < '3.13' and extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' - lz4>=1.7.4.2 ; extra == 'all' - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' @@ -1964,18 +4207,18 @@ packages: - sympy ; extra == 'all' - xattr ; sys_platform == 'darwin' and extra == 'all' - skia-pathops>=0.5.0 ; extra == 'all' - - uharfbuzz>=0.23.0 ; extra == 'all' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d6/8a/de9cc0540f542963ba5e8f3a1f6ad48fa211badc3177783b9d5cadf79b5d/fonttools-4.60.1-cp313-cp313-macosx_10_13_x86_64.whl + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/69/12/bf9f4eaa2fad039356cc627587e30ed008c03f1cebd3034376b5ee8d1d44/fonttools-4.61.1-cp311-cp311-macosx_10_9_universal2.whl name: fonttools - version: 4.60.1 - sha256: eedacb5c5d22b7097482fa834bda0dafa3d914a4e829ec83cdea2a01f8c813c4 + version: 4.61.1 + sha256: c6604b735bb12fef8e0efd5578c9fb5d3d8532d5001ea13a19cddf295673ee09 requires_dist: - lxml>=4.0 ; extra == 'lxml' - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' - zopfli>=0.1.4 ; extra == 'woff' - - unicodedata2>=15.1.0 ; python_full_version < '3.13' and extra == 'unicode' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' - lz4>=1.7.4.2 ; extra == 'graphite' - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' @@ -1984,12 +4227,12 @@ packages: - sympy ; extra == 'symfont' - xattr ; sys_platform == 'darwin' and extra == 'type1' - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.23.0 ; extra == 'repacker' + - uharfbuzz>=0.45.0 ; extra == 'repacker' - lxml>=4.0 ; extra == 'all' - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' - zopfli>=0.1.4 ; extra == 'all' - - unicodedata2>=15.1.0 ; python_full_version < '3.13' and extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' - lz4>=1.7.4.2 ; extra == 'all' - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' @@ -1998,8 +4241,110 @@ packages: - sympy ; extra == 'all' - xattr ; sys_platform == 'darwin' and extra == 'all' - skia-pathops>=0.5.0 ; extra == 'all' - - uharfbuzz>=0.23.0 ; extra == 'all' - requires_python: '>=3.9' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/79/61/1ca198af22f7dd22c17ab86e9024ed3c06299cfdb08170640e9996d501a0/fonttools-4.61.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: fonttools + version: 4.61.1 + sha256: 75c1a6dfac6abd407634420c93864a1e274ebc1c7531346d9254c0d8f6ca00f9 + requires_dist: + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a3/4b/d67eedaed19def5967fade3297fed8161b25ba94699efc124b14fb68cdbc/fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl + name: fonttools + version: 4.61.1 + sha256: 64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5 + requires_dist: + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ac/49/4138d1acb6261499bedde1c07f8c2605d1d8f9d77a151e5507fd3ef084b6/fonttools-4.61.1-cp311-cp311-macosx_10_9_x86_64.whl + name: fonttools + version: 4.61.1 + sha256: 5ce02f38a754f207f2f06557523cd39a06438ba3aafc0639c477ac409fc64e37 + requires_dist: + - lxml>=4.0 ; extra == 'lxml' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'woff' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'woff' + - zopfli>=0.1.4 ; extra == 'woff' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'unicode' + - lz4>=1.7.4.2 ; extra == 'graphite' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'interpolatable' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'interpolatable' + - pycairo ; extra == 'interpolatable' + - matplotlib ; extra == 'plot' + - sympy ; extra == 'symfont' + - xattr ; sys_platform == 'darwin' and extra == 'type1' + - skia-pathops>=0.5.0 ; extra == 'pathops' + - uharfbuzz>=0.45.0 ; extra == 'repacker' + - lxml>=4.0 ; extra == 'all' + - brotli>=1.0.1 ; platform_python_implementation == 'CPython' and extra == 'all' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'all' + - zopfli>=0.1.4 ; extra == 'all' + - unicodedata2>=17.0.0 ; python_full_version < '3.15' and extra == 'all' + - lz4>=1.7.4.2 ; extra == 'all' + - scipy ; platform_python_implementation != 'PyPy' and extra == 'all' + - munkres ; platform_python_implementation == 'PyPy' and extra == 'all' + - pycairo ; extra == 'all' + - matplotlib ; extra == 'all' + - sympy ; extra == 'all' + - xattr ; sys_platform == 'darwin' and extra == 'all' + - skia-pathops>=0.5.0 ; extra == 'all' + - uharfbuzz>=0.45.0 ; extra == 'all' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl name: fqdn version: 1.5.1 @@ -2007,16 +4352,31 @@ packages: requires_dist: - cached-property>=1.3.0 ; python_full_version < '3.8' requires_python: '>=2.7,!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,<4' +- pypi: https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl + name: frozenlist + version: 1.8.0 + sha256: ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl name: frozenlist version: 1.8.0 sha256: f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40 requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl + name: frozenlist + version: 1.8.0 + sha256: 2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl name: frozenlist version: 1.8.0 sha256: 96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7 requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl + name: frozenlist + version: 1.8.0 + sha256: fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93 + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl name: frozenlist version: 1.8.0 @@ -2027,11 +4387,75 @@ packages: version: 1.8.0 sha256: 878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231 requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/df/b5/7610b6bd13e4ae77b96ba85abea1c8cb249683217ef09ac9e0ae93f25a91/frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl + name: frozenlist + version: 1.8.0 + sha256: 17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl + name: funcy + version: '2.0' + sha256: 53df23c8bb1651b12f095df764bfb057935d49537a56de211b098f4c79614bb0 +- pypi: https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl + name: ghp-import + version: 2.1.0 + sha256: 8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619 + requires_dist: + - python-dateutil>=2.8.1 + - twine ; extra == 'dev' + - markdown ; extra == 'dev' + - flake8 ; extra == 'dev' + - wheel ; extra == 'dev' +- pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl + name: gitdb + version: 4.0.12 + sha256: 67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf + requires_dist: + - smmap>=3.0.1,<6 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl + name: gitpython + version: 3.1.46 + sha256: 79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058 + requires_dist: + - gitdb>=4.0.1,<5 + - typing-extensions>=3.10.0.2 ; python_full_version < '3.10' + - coverage[toml] ; extra == 'test' + - ddt>=1.1.1,!=1.4.3 ; extra == 'test' + - mock ; python_full_version < '3.8' and extra == 'test' + - mypy==1.18.2 ; python_full_version >= '3.9' and extra == 'test' + - pre-commit ; extra == 'test' + - pytest>=7.3.1 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-instafail ; extra == 'test' + - pytest-mock ; extra == 'test' + - pytest-sugar ; extra == 'test' + - typing-extensions ; python_full_version < '3.11' and extra == 'test' + - sphinx>=7.1.2,<7.2 ; extra == 'doc' + - sphinx-rtd-theme ; extra == 'doc' + - sphinx-autodoc-typehints ; extra == 'doc' + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl + name: griffelib + version: 2.0.0 + sha256: 01284878c966508b6d6f1dbff9b6fa607bc062d8261c5c7253cb285b06422a7f + requires_dist: + - pip>=24.0 ; extra == 'pypi' + - platformdirs>=4.2 ; extra == 'pypi' + - wheel>=0.42 ; extra == 'pypi' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl name: h11 version: 0.16.0 sha256: 63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/23/95/499b4e56452ef8b6c95a271af0dde08dac4ddb70515a75f346d4f400579b/h5py-3.15.1-cp311-cp311-win_amd64.whl + name: h5py + version: 3.15.1 + sha256: 550e51131376889656feec4aff2170efc054a7fe79eb1da3bb92e1625d1ac878 + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/31/96/ba99a003c763998035b0de4c299598125df5fc6c9ccf834f152ddd60e0fb/h5py-3.15.1-cp313-cp313-macosx_11_0_arm64.whl name: h5py version: 3.15.1 @@ -2039,6 +4463,13 @@ packages: requires_dist: - numpy>=1.21.2 requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/41/fd/8349b48b15b47768042cff06ad6e1c229f0a4bd89225bf6b6894fea27e6d/h5py-3.15.1-cp311-cp311-macosx_10_9_x86_64.whl + name: h5py + version: 3.15.1 + sha256: 5aaa330bcbf2830150c50897ea5dcbed30b5b6d56897289846ac5b9e529ec243 + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/88/b3/40207e0192415cbff7ea1d37b9f24b33f6d38a5a2f5d18a678de78f967ae/h5py-3.15.1-cp313-cp313-macosx_10_13_x86_64.whl name: h5py version: 3.15.1 @@ -2046,6 +4477,20 @@ packages: requires_dist: - numpy>=1.21.2 requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/8b/23/4ab1108e87851ccc69694b03b817d92e142966a6c4abd99e17db77f2c066/h5py-3.15.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: h5py + version: 3.15.1 + sha256: 5b849ba619a066196169763c33f9f0f02e381156d61c03e000bb0100f9950faf + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/c1/b0/1c628e26a0b95858f54aba17e1599e7f6cd241727596cc2580b72cb0a9bf/h5py-3.15.1-cp311-cp311-macosx_11_0_arm64.whl + name: h5py + version: 3.15.1 + sha256: c970fb80001fffabb0109eaf95116c8e7c0d3ca2de854e0901e8a04c1f098509 + requires_dist: + - numpy>=1.21.2 + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/d9/69/4402ea66272dacc10b298cca18ed73e1c0791ff2ae9ed218d3859f9698ac/h5py-3.15.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl name: h5py version: 3.15.1 @@ -2060,18 +4505,6 @@ packages: requires_dist: - numpy>=1.21.2 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/04/35/aa8738d6674aba09d3f0c77a1c40aee1dbf10e1b26d03cbd987aa6642e86/hatchling-1.21.0-py3-none-any.whl - name: hatchling - version: 1.21.0 - sha256: b33ef0ecdee6dbfd28c21ca30df459ba1d566050d033f8b5a1d0e26e5606d26b - requires_dist: - - editables>=0.3 - - packaging>=21.3 - - pathspec>=0.10.1 - - pluggy>=1.0.0 - - tomli>=1.2.2 ; python_full_version < '3.11' - - trove-classifiers - requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl name: httpcore version: 1.0.9 @@ -2102,52 +4535,139 @@ packages: - socksio==1.* ; extra == 'socks' - zstandard>=0.18.0 ; extra == 'zstd' requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - sha256: 71e750d509f5fa3421087ba88ef9a7b9be11c53174af3aa4d06aff4c18b38e8e - md5: 8b189310083baabfb622af68fd9d3ae3 +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda + sha256: 142a722072fa96cf16ff98eaaf641f54ab84744af81754c292cb81e0881c0329 + md5: 186a18e3ba246eccfc7cff00cd19a870 depends: - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 + - libgcc >=14 + - libstdcxx >=14 + license: MIT + license_family: MIT + purls: [] + size: 12728445 + timestamp: 1767969922681 +- conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda + sha256: f3066beae7fe3002f09c8a412cdf1819f49a2c9a485f720ec11664330cf9f1fe + md5: 30334add4de016489b731c6662511684 + depends: + - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 12129203 - timestamp: 1720853576813 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda - sha256: 9ba12c93406f3df5ab0a43db8a4b4ef67a5871dfd401010fbe29b218b2cbe620 - md5: 5eb22c1d7b3fc4abb50d92d621583137 + size: 12263724 + timestamp: 1767970604977 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda + sha256: 24bc62335106c30fecbcc1dba62c5eba06d18b90ea1061abd111af7b9c89c2d7 + md5: 114e6bfe7c5ad2525eb3597acdbf2300 depends: - __osx >=11.0 license: MIT license_family: MIT purls: [] - size: 11857802 - timestamp: 1720853997952 + size: 12389400 + timestamp: 1772209104304 +- pypi: https://files.pythonhosted.org/packages/40/66/71c1227dff78aaeb942fed29dd5651f2aec166cc7c9aeea3e8b26a539b7d/identify-2.6.17-py2.py3-none-any.whl + name: identify + version: 2.6.17 + sha256: be5f8412d5ed4b20f2bd41a65f920990bdccaa6a4a18a08f1eefdcd0bdd885f0 + requires_dist: + - ukkonen ; extra == 'license' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl name: idna version: '3.11' sha256: 771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea requires_dist: - - ruff>=0.6.2 ; extra == 'all' - - mypy>=1.11.2 ; extra == 'all' - - pytest>=8.3.2 ; extra == 'all' - - flake8>=7.1.1 ; extra == 'all' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl - name: imagesize - version: 1.4.1 - sha256: 0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' + - ruff>=0.6.2 ; extra == 'all' + - mypy>=1.11.2 ; extra == 'all' + - pytest>=8.3.2 ; extra == 'all' + - flake8>=7.1.1 ; extra == 'all' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl + name: importlib-metadata + version: 8.7.1 + sha256: 5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 + requires_dist: + - zipp>=3.20 + - pytest>=6,!=8.1.* ; extra == 'test' + - packaging ; extra == 'test' + - pyfakefs ; extra == 'test' + - flufl-flake8 ; extra == 'test' + - pytest-perf>=0.9.2 ; extra == 'test' + - jaraco-test>=5.4 ; extra == 'test' + - sphinx>=3.5 ; extra == 'doc' + - jaraco-packaging>=9.3 ; extra == 'doc' + - rst-linker>=1.9 ; extra == 'doc' + - furo ; extra == 'doc' + - sphinx-lint ; extra == 'doc' + - jaraco-tidelift>=1.4 ; extra == 'doc' + - ipython ; extra == 'perf' + - pytest-checkdocs>=2.4 ; extra == 'check' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' + - pytest-cov ; extra == 'cover' + - pytest-enabler>=3.4 ; extra == 'enabler' + - pytest-mypy>=1.0.1 ; extra == 'type' + - mypy<1.19 ; platform_python_implementation == 'PyPy' and extra == 'type' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl + name: importlib-resources + version: 6.5.2 + sha256: 789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec + requires_dist: + - zipp>=3.1.0 ; python_full_version < '3.10' + - pytest>=6,!=8.1.* ; extra == 'test' + - zipp>=3.17 ; extra == 'test' + - jaraco-test>=5.4 ; extra == 'test' + - sphinx>=3.5 ; extra == 'doc' + - jaraco-packaging>=9.3 ; extra == 'doc' + - rst-linker>=1.9 ; extra == 'doc' + - furo ; extra == 'doc' + - sphinx-lint ; extra == 'doc' + - jaraco-tidelift>=1.4 ; extra == 'doc' + - pytest-checkdocs>=2.4 ; extra == 'check' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' + - pytest-cov ; extra == 'cover' + - pytest-enabler>=2.2 ; extra == 'enabler' + - pytest-mypy ; extra == 'type' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl name: iniconfig version: 2.3.0 sha256: f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/12/c9/6869a1dcf4aaf309b9543ec070be3ec3adebee7c9bec9af8c230494134b9/interrogate-1.7.0-py3-none-any.whl + name: interrogate + version: 1.7.0 + sha256: b13ff4dd8403369670e2efe684066de9fcb868ad9d7f2b4095d8112142dc9d12 + requires_dist: + - attrs + - click>=7.1 + - colorama + - py + - tabulate + - tomli ; python_full_version < '3.11' + - cairosvg ; extra == 'dev' + - sphinx ; extra == 'dev' + - sphinx-autobuild ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-mock ; extra == 'dev' + - coverage[toml] ; extra == 'dev' + - wheel ; extra == 'dev' + - pre-commit ; extra == 'dev' + - sphinx ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - cairosvg ; extra == 'png' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-mock ; extra == 'tests' + - coverage[toml] ; extra == 'tests' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/f6/d8/502954a4ec0efcf264f99b65b41c3c54e65a647d9f0d6f62cd02227d242c/ipykernel-6.31.0-py3-none-any.whl name: ipykernel - version: 7.1.0 - sha256: 763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c + version: 6.31.0 + sha256: abe5386f6ced727a70e0eb0cf1da801fa7c5fa6ff82147747d5a0406cd8c94af requires_dist: - appnope>=0.1.2 ; sys_platform == 'darwin' - comm>=0.1.1 @@ -2169,8 +4689,8 @@ packages: - intersphinx-registry ; extra == 'docs' - myst-parser ; extra == 'docs' - pydata-sphinx-theme ; extra == 'docs' + - sphinx ; extra == 'docs' - sphinx-autodoc-typehints ; extra == 'docs' - - sphinx<8.2.0 ; extra == 'docs' - sphinxcontrib-github-alt ; extra == 'docs' - sphinxcontrib-spelling ; extra == 'docs' - trio ; extra == 'docs' @@ -2183,11 +4703,32 @@ packages: - pytest-cov ; extra == 'test' - pytest-timeout ; extra == 'test' - pytest>=7.0,<9 ; extra == 'test' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/05/aa/62893d6a591d337aa59dcc4c6f6c842f1fe20cd72c8c5c1f980255243252/ipython-9.7.0-py3-none-any.whl + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/12/b3/88c0ef22878c86035f058df0ac6c171319ffd0aa52a406455ed3a3847566/ipympl-0.10.0-py3-none-any.whl + name: ipympl + version: 0.10.0 + sha256: a09c4f0ff86490cc62aed45e53b912fb706e3ec3506c4a51ce4a670d6667f5ce + requires_dist: + - ipython<10 + - ipywidgets>=7.6.0,<9 + - matplotlib>=3.5.0,<4 + - numpy + - pillow + - traitlets<6 + - intersphinx-registry ; extra == 'docs' + - myst-nb ; extra == 'docs' + - sphinx-book-theme ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-thebe ; extra == 'docs' + - sphinx-togglebutton ; extra == 'docs' + - sphinx>=1.5 ; extra == 'docs' + - nbval>=0.11.0 ; extra == 'test' + - pytest>=9.0.2 ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3d/aa/898dec789a05731cd5a9f50605b7b44a72bd198fd0d4528e11fc610177cc/ipython-9.10.0-py3-none-any.whl name: ipython - version: 9.7.0 - sha256: bce8ac85eb9521adc94e1845b4c03d88365fd6ac2f4908ec4ed1eb1b0a065f9f + version: 9.10.0 + sha256: c6ab68cc23bba8c7e18e9b932797014cc61ea7fd6f19de180ab9ba73e65ee58d requires_dist: - colorama>=0.4.4 ; sys_platform == 'win32' - decorator>=4.3.2 @@ -2227,7 +4768,8 @@ packages: - pandas>2.1 ; extra == 'test-extra' - trio>=0.1.0 ; extra == 'test-extra' - matplotlib>3.9 ; extra == 'matplotlib' - - ipython[doc,matplotlib,test,test-extra] ; extra == 'all' + - ipython[doc,matplotlib,terminal,test,test-extra] ; extra == 'all' + - argcomplete>=3.0 ; extra == 'all' requires_python: '>=3.11' - pypi: https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl name: ipython-pygments-lexers @@ -2236,6 +4778,22 @@ packages: requires_dist: - pygments requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl + name: ipywidgets + version: 8.1.8 + sha256: ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e + requires_dist: + - comm>=0.1.3 + - ipython>=6.1.0 + - traitlets>=4.3.1 + - widgetsnbextension~=4.0.14 + - jupyterlab-widgets~=3.0.15 + - jsonschema ; extra == 'test' + - ipykernel ; extra == 'test' + - pytest>=3.6.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytz ; extra == 'test' + requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl name: isoduration version: 20.11.0 @@ -2291,37 +4849,34 @@ packages: - markupsafe>=2.0 - babel>=2.7 ; extra == 'i18n' requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/85/e2/05328bd2621be49a6fed9e3030b1e51a2d04537d3f816d211b9cc53c5262/json5-0.12.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/72/b9/313e8f2f2e9517ae050a692ae7b3e4b3f17cc5e6dfea0db51fe14e586580/jinja2_ansible_filters-1.3.2-py3-none-any.whl + name: jinja2-ansible-filters + version: 1.3.2 + sha256: e1082f5564917649c76fed239117820610516ec10f87735d0338688800a55b34 + requires_dist: + - jinja2 + - pyyaml + - pytest ; extra == 'test' + - pytest-cov ; extra == 'test' +- pypi: https://files.pythonhosted.org/packages/d7/9e/038522f50ceb7e74f1f991bf1b699f24b0c2bbe7c390dd36ad69f4582258/json5-0.13.0-py3-none-any.whl name: json5 - version: 0.12.1 - sha256: d9c9b3bc34a5f54d43c35e11ef7cb87d8bdd098c6ace87117a7b7e83e705c1d5 - requires_dist: - - build==1.2.2.post1 ; extra == 'dev' - - coverage==7.5.4 ; python_full_version < '3.9' and extra == 'dev' - - coverage==7.8.0 ; python_full_version >= '3.9' and extra == 'dev' - - mypy==1.14.1 ; python_full_version < '3.9' and extra == 'dev' - - mypy==1.15.0 ; python_full_version >= '3.9' and extra == 'dev' - - pip==25.0.1 ; extra == 'dev' - - pylint==3.2.7 ; python_full_version < '3.9' and extra == 'dev' - - pylint==3.3.6 ; python_full_version >= '3.9' and extra == 'dev' - - ruff==0.11.2 ; extra == 'dev' - - twine==6.1.0 ; extra == 'dev' - - uv==0.6.11 ; extra == 'dev' + version: 0.13.0 + sha256: 9a08e1dd65f6a4d4c6fa82d216cf2477349ec2346a38fd70cc11d2557499fbcc requires_python: '>=3.8.0' - pypi: https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl name: jsonpointer version: 3.0.0 sha256: 13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942 requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl name: jsonschema - version: 4.25.1 - sha256: 3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63 + version: 4.26.0 + sha256: d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce requires_dist: - attrs>=22.2.0 - jsonschema-specifications>=2023.3.6 - referencing>=0.28.4 - - rpds-py>=0.7.1 + - rpds-py>=0.25.0 - fqdn ; extra == 'format' - idna ; extra == 'format' - isoduration ; extra == 'format' @@ -2339,7 +4894,7 @@ packages: - rfc3987-syntax>=1.1.0 ; extra == 'format-nongpl' - uri-template ; extra == 'format-nongpl' - webcolors>=24.6.0 ; extra == 'format-nongpl' - requires_python: '>=3.9' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl name: jsonschema-specifications version: 2025.9.1 @@ -2347,16 +4902,15 @@ packages: requires_dist: - referencing>=0.31.0 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl name: jupyter-client - version: 8.6.3 - sha256: e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f + version: 8.8.0 + sha256: f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a requires_dist: - - importlib-metadata>=4.8.3 ; python_full_version < '3.10' - - jupyter-core>=4.12,!=5.0.* + - jupyter-core>=5.1 - python-dateutil>=2.8.2 - - pyzmq>=23.0 - - tornado>=6.2 + - pyzmq>=25.0 + - tornado>=6.4.1 - traitlets>=5.3 - ipykernel ; extra == 'docs' - myst-parser ; extra == 'docs' @@ -2365,16 +4919,19 @@ packages: - sphinx>=4 ; extra == 'docs' - sphinxcontrib-github-alt ; extra == 'docs' - sphinxcontrib-spelling ; extra == 'docs' + - orjson ; extra == 'orjson' + - anyio ; extra == 'test' - coverage ; extra == 'test' - ipykernel>=6.14 ; extra == 'test' - - mypy ; extra == 'test' + - msgpack ; extra == 'test' + - mypy ; platform_python_implementation != 'PyPy' and extra == 'test' - paramiko ; sys_platform == 'win32' and extra == 'test' - pre-commit ; extra == 'test' + - pytest ; extra == 'test' - pytest-cov ; extra == 'test' - - pytest-jupyter[client]>=0.4.1 ; extra == 'test' + - pytest-jupyter[client]>=0.6.2 ; extra == 'test' - pytest-timeout ; extra == 'test' - - pytest<8.2.0 ; extra == 'test' - requires_python: '>=3.8' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl name: jupyter-core version: 5.9.1 @@ -2477,10 +5034,10 @@ packages: - pytest>=7.0,<9 ; extra == 'test' - requests ; extra == 'test' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl name: jupyter-server-terminals - version: 0.5.3 - sha256: 41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa + version: 0.5.4 + sha256: 55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14 requires_dist: - pywinpty>=2.0.3 ; os_name == 'nt' - terminado>=0.8.3 @@ -2501,10 +5058,10 @@ packages: - pytest-timeout ; extra == 'test' - pytest>=7.0 ; extra == 'test' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/6c/1e/5a4d5498eba382fee667ed797cf64ae5d1b13b04356df62f067f48bb0f61/jupyterlab-4.5.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl name: jupyterlab - version: 4.5.0 - sha256: 88e157c75c1afff64c7dc4b801ec471450b922a4eae4305211ddd40da8201c8a + version: 4.5.5 + sha256: a35694a40a8e7f2e82f387472af24e61b22adcce87b5a8ab97a5d9c486202a6d requires_dist: - async-lru>=1.0.0 - httpx>=0.25.0,<1 @@ -2605,16 +5162,123 @@ packages: - strict-rfc3339 ; extra == 'test' - werkzeug ; extra == 'test' requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl + name: jupyterlab-widgets + version: 3.0.16 + sha256: 45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/f7/5a/488f492b49b712ca38326e12c78d0d48ab6be682a2989ce533f0f2c4dfd2/jupyterquiz-2.9.6.2-py2.py3-none-any.whl + name: jupyterquiz + version: 2.9.6.2 + sha256: f60f358c809d06a38c423c804740c1113c8840e130227aef50694a9201474bef +- pypi: https://files.pythonhosted.org/packages/16/5a/736dd2f4535dbf3bf26523f9158c011389ef88dd06ec2eef67fd744f1c7b/jupytext-1.19.1-py3-none-any.whl + name: jupytext + version: 1.19.1 + sha256: d8975035155d034bdfde5c0c37891425314b7ea8d3a6c4b5d18c294348714cd9 + requires_dist: + - markdown-it-py>=1.0 + - mdit-py-plugins + - nbformat + - packaging + - pyyaml + - tomli ; python_full_version < '3.11' + - autopep8 ; extra == 'dev' + - black ; extra == 'dev' + - flake8 ; extra == 'dev' + - gitpython ; extra == 'dev' + - ipykernel ; extra == 'dev' + - isort ; extra == 'dev' + - jupyter-fs[fs]>=1.0 ; extra == 'dev' + - jupyter-server!=2.11 ; extra == 'dev' + - marimo>=0.17.6,<=0.19.4 ; extra == 'dev' + - nbconvert ; extra == 'dev' + - pre-commit ; extra == 'dev' + - pytest ; extra == 'dev' + - pytest-asyncio ; extra == 'dev' + - pytest-cov>=2.6.1 ; extra == 'dev' + - pytest-randomly ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - sphinx ; extra == 'dev' + - sphinx-gallery>=0.8 ; extra == 'dev' + - myst-parser ; extra == 'docs' + - sphinx ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-rtd-theme ; extra == 'docs' + - pytest ; extra == 'test' + - pytest-asyncio ; extra == 'test' + - pytest-randomly ; extra == 'test' + - pytest-xdist ; extra == 'test' + - black ; extra == 'test-cov' + - ipykernel ; extra == 'test-cov' + - jupyter-server!=2.11 ; extra == 'test-cov' + - nbconvert ; extra == 'test-cov' + - pytest ; extra == 'test-cov' + - pytest-asyncio ; extra == 'test-cov' + - pytest-cov>=2.6.1 ; extra == 'test-cov' + - pytest-randomly ; extra == 'test-cov' + - pytest-xdist ; extra == 'test-cov' + - autopep8 ; extra == 'test-external' + - black ; extra == 'test-external' + - flake8 ; extra == 'test-external' + - gitpython ; extra == 'test-external' + - ipykernel ; extra == 'test-external' + - isort ; extra == 'test-external' + - jupyter-fs[fs]>=1.0 ; extra == 'test-external' + - jupyter-server!=2.11 ; extra == 'test-external' + - marimo>=0.17.6,<=0.19.4 ; extra == 'test-external' + - nbconvert ; extra == 'test-external' + - pre-commit ; extra == 'test-external' + - pytest ; extra == 'test-external' + - pytest-asyncio ; extra == 'test-external' + - pytest-randomly ; extra == 'test-external' + - pytest-xdist ; extra == 'test-external' + - sphinx ; extra == 'test-external' + - sphinx-gallery>=0.8 ; extra == 'test-external' + - black ; extra == 'test-functional' + - pytest ; extra == 'test-functional' + - pytest-asyncio ; extra == 'test-functional' + - pytest-randomly ; extra == 'test-functional' + - pytest-xdist ; extra == 'test-functional' + - black ; extra == 'test-integration' + - ipykernel ; extra == 'test-integration' + - jupyter-server!=2.11 ; extra == 'test-integration' + - nbconvert ; extra == 'test-integration' + - pytest ; extra == 'test-integration' + - pytest-asyncio ; extra == 'test-integration' + - pytest-randomly ; extra == 'test-integration' + - pytest-xdist ; extra == 'test-integration' + - bash-kernel ; extra == 'test-ui' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/2d/7a/9d90a151f558e29c3936b8a47ac770235f436f2120aca41a6d5f3d62ae8d/kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl name: kiwisolver version: 1.4.9 sha256: 1a12cf6398e8a0a001a059747a1cbf24705e18fe413bc22de7b3d15c67cffe3f requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/31/a2/a12a503ac1fd4943c50f9822678e8015a790a13b5490354c68afb8489814/kiwisolver-1.4.9-cp311-cp311-macosx_11_0_arm64.whl + name: kiwisolver + version: 1.4.9 + sha256: 2405a7d98604b87f3fc28b1716783534b1b4b8510d8142adca34ee0bc3c87543 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/3b/c6/f8df8509fd1eee6c622febe54384a96cfaf4d43bf2ccec7a0cc17e4715c9/kiwisolver-1.4.9-cp311-cp311-win_amd64.whl + name: kiwisolver + version: 1.4.9 + sha256: be6a04e6c79819c9a8c2373317d19a96048e5a3f90bec587787e86a1153883c2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/66/e1/e533435c0be77c3f64040d68d7a657771194a63c279f55573188161e81ca/kiwisolver-1.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: kiwisolver + version: 1.4.9 + sha256: dc1ae486f9abcef254b5618dfb4113dd49f94c68e3e027d03cf0143f3f772b61 + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/75/bd/f1a5d894000941739f2ae1b65a32892349423ad49c2e6d0771d0bad3fae4/kiwisolver-1.4.9-cp313-cp313-win_amd64.whl name: kiwisolver version: 1.4.9 sha256: dd0a578400839256df88c16abddf9ba14813ec5f21362e1fe65022e00c883d4d requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a0/c0/27fe1a68a39cf62472a300e2879ffc13c0538546c359b86f149cc19f6ac3/kiwisolver-1.4.9-cp311-cp311-macosx_10_9_x86_64.whl + name: kiwisolver + version: 1.4.9 + sha256: 39a219e1c81ae3b103643d2aedb90f1ef22650deb266ff12a19e7773f3e5f089 + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/ca/f0/f44f50c9f5b1a1860261092e3bc91ecdc9acda848a8b8c6abfda4a24dd5c/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl name: kiwisolver version: 1.4.9 @@ -2635,102 +5299,292 @@ packages: - atomicwrites ; extra == 'atomic-cache' - interegular>=0.3.1,<0.4.0 ; extra == 'interegular' requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-bootstrap_ha15bf96_3.conda - sha256: 7dfdf5500318521827c590fbda0fce5d6bda1d15dfee11b677d420580d18ccc0 - md5: 3036ca5b895b7f5146c5a25486234a68 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda + sha256: 565941ac1f8b0d2f2e8f02827cbca648f4d18cd461afc31f15604cd291b5c5f3 + md5: 12bd9a3f089ee6c9266a37dab82afabd depends: - __glibc >=2.17,<3.0.a0 + - zstd >=1.5.7,<1.6.0a0 constrains: - - binutils_impl_linux-64 2.45 + - binutils_impl_linux-64 2.45.1 license: GPL-3.0-only + license_family: GPL + purls: [] + size: 725507 + timestamp: 1770267139900 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + sha256: a7a4481a4d217a3eadea0ec489826a69070fcc3153f00443aa491ed21527d239 + md5: 6f7b4302263347698fd24565fbf11310 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + constrains: + - libabseil-static =20260107.1=cxx17* + - abseil-cpp =20260107.1 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 1384817 + timestamp: 1770863194876 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libabseil-20260107.1-cxx17_h7ed6875_0.conda + sha256: 2b4ff36082ddfbacc47ac6e11d4dd9f3403cd109ce8d7f0fbee0cdd47cdef013 + md5: 317f40d7bd7bf6d54b56d4a5b5f5085d + depends: + - __osx >=10.13 + - libcxx >=19 + constrains: + - libabseil-static =20260107.1=cxx17* + - abseil-cpp =20260107.1 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 1217836 + timestamp: 1770863510112 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda + sha256: 756611fbb8d2957a5b4635d9772bd8432cb6ddac05580a6284cca6fdc9b07fca + md5: bb65152e0d7c7178c0f1ee25692c9fd1 + depends: + - __osx >=11.0 + - libcxx >=19 + constrains: + - abseil-cpp =20260107.1 + - libabseil-static =20260107.1=cxx17* + license: Apache-2.0 + license_family: Apache + purls: [] + size: 1229639 + timestamp: 1770863511331 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + sha256: 318f36bd49ca8ad85e6478bd8506c88d82454cc008c1ac1c6bf00a3c42fa610e + md5: 72c8fd1af66bd67bf580645b426513ed + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 79965 + timestamp: 1764017188531 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda + sha256: 4c19b211b3095f541426d5a9abac63e96a5045e509b3d11d4f9482de53efe43b + md5: f157c098841474579569c85a60ece586 + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + purls: [] + size: 78854 + timestamp: 1764017554982 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + sha256: a7cb9e660531cf6fbd4148cff608c85738d0b76f0975c5fc3e7d5e92840b7229 + md5: 006e7ddd8a110771134fcc4e1e3a6ffa + depends: + - __osx >=11.0 + license: MIT + license_family: MIT purls: [] - size: 729222 - timestamp: 1763768158810 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda - sha256: 1e1b08f6211629cbc2efe7a5bca5953f8f6b3cae0eeb04ca4dacee1bd4e2db2f - md5: 8b09ae86839581147ef2e5c5e229d164 + size: 79443 + timestamp: 1764017945924 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + sha256: 12fff21d38f98bc446d82baa890e01fd82e3b750378fedc720ff93522ffb752b + md5: 366b40a69f0ad6072561c1d09301c886 + depends: + - __glibc >=2.17,<3.0.a0 + - libbrotlicommon 1.2.0 hb03c661_1 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 34632 + timestamp: 1764017199083 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda + sha256: 729158be90ae655a4e0427fe4079767734af1f9b69ff58cf94ca6e8d4b3eb4b7 + md5: 63186ac7a8a24b3528b4b14f21c03f54 + depends: + - __osx >=10.13 + - libbrotlicommon 1.2.0 h8616949_1 + license: MIT + license_family: MIT + purls: [] + size: 30835 + timestamp: 1764017584474 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + sha256: 2eae444039826db0454b19b52a3390f63bfe24f6b3e63089778dd5a5bf48b6bf + md5: 079e88933963f3f149054eec2c487bc2 + depends: + - __osx >=11.0 + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: [] + size: 29452 + timestamp: 1764017979099 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + sha256: a0c15c79997820bbd3fbc8ecf146f4fe0eca36cc60b62b63ac6cf78857f1dd0d + md5: 4ffbb341c8b616aa2494b6afb26a0c5f + depends: + - __glibc >=2.17,<3.0.a0 + - libbrotlicommon 1.2.0 hb03c661_1 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 298378 + timestamp: 1764017210931 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda + sha256: 8ece7b41b6548d6601ac2c2cd605cf2261268fc4443227cc284477ed23fbd401 + md5: 12a58fd3fc285ce20cf20edf21a0ff8f + depends: + - __osx >=10.13 + - libbrotlicommon 1.2.0 h8616949_1 + license: MIT + license_family: MIT + purls: [] + size: 310355 + timestamp: 1764017609985 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + sha256: 01436c32bb41f9cb4bcf07dda647ce4e5deb8307abfc3abdc8da5317db8189d1 + md5: b2b7c8288ca1a2d71ff97a8e6a1e8883 + depends: + - __osx >=11.0 + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: [] + size: 290754 + timestamp: 1764018009077 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.0-h19cb2f5_1.conda + sha256: fa002b43752fe5860e588435525195324fe250287105ebd472ac138e97de45e6 + md5: 836389b6b9ae58f3fbcf7cafebd5c7f2 + depends: + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + purls: [] + size: 570141 + timestamp: 1772001147762 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.0-h55c6f16_1.conda + sha256: ce1049fa6fda9cf08ff1c50fb39573b5b0ea6958375d8ea7ccd8456ab81a0bcb + md5: e9c56daea841013e7774b5cd46f41564 + depends: + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + purls: [] + size: 568910 + timestamp: 1772001095642 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 + md5: 172bf1cd1ff8629f2b1179945ed45055 + depends: + - libgcc-ng >=12 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 112766 + timestamp: 1702146165126 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda + sha256: 0d238488564a7992942aa165ff994eca540f687753b4f0998b29b4e4d030ff43 + md5: 899db79329439820b7e8f8de41bca902 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 106663 + timestamp: 1702146352558 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + sha256: 95cecb3902fbe0399c3a7e67a5bed1db813e5ab0e22f4023a5e0f722f2cc214f + md5: 36d33e440c31857372a72137f78bacf5 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 107458 + timestamp: 1702146414478 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda + sha256: d78f1d3bea8c031d2f032b760f36676d87929b18146351c4464c66b0869df3f5 + md5: e7f7ce06ec24cfcfb9e36d28cf82ba57 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 constrains: - - expat 2.7.3.* + - expat 2.7.4.* license: MIT license_family: MIT purls: [] - size: 76643 - timestamp: 1763549731408 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda - sha256: d11b3a6ce5b2e832f430fd112084533a01220597221bee16d6c7dc3947dffba6 - md5: 222e0732a1d0780a622926265bee14ef + size: 76798 + timestamp: 1771259418166 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda + sha256: 8d9d79b2de7d6f335692391f5281607221bf5d040e6724dad4c4d77cd603ce43 + md5: a684eb8a19b2aa68fde0267df172a1e3 depends: - __osx >=10.13 constrains: - - expat 2.7.3.* + - expat 2.7.4.* license: MIT license_family: MIT purls: [] - size: 74058 - timestamp: 1763549886493 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda - sha256: fce22610ecc95e6d149e42a42fbc3cc9d9179bd4eb6232639a60f06e080eec98 - md5: b79875dbb5b1db9a4a22a4520f918e1a + size: 74578 + timestamp: 1771260142624 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda + sha256: 03887d8080d6a8fe02d75b80929271b39697ecca7628f0657d7afaea87761edf + md5: a92e310ae8dfc206ff449f362fc4217f depends: - __osx >=11.0 constrains: - - expat 2.7.3.* + - expat 2.7.4.* license: MIT license_family: MIT purls: [] - size: 67800 - timestamp: 1763549994166 -- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda - sha256: 844ab708594bdfbd7b35e1a67c379861bcd180d6efe57b654f482ae2f7f5c21e - md5: 8c9e4f1a0e688eef2e95711178061a0f + size: 68199 + timestamp: 1771260020767 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda + sha256: b31f6fb629c4e17885aaf2082fb30384156d16b48b264e454de4a06a313b533d + md5: 1c1ced969021592407f16ada4573586d depends: - ucrt >=10.0.20348.0 - vc >=14.3,<15 - vc14_runtime >=14.44.35208 constrains: - - expat 2.7.3.* + - expat 2.7.4.* license: MIT license_family: MIT purls: [] - size: 70137 - timestamp: 1763550049107 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda - sha256: 25cbdfa65580cfab1b8d15ee90b4c9f1e0d72128f1661449c9a999d341377d54 - md5: 35f29eec58405aaf55e01cb470d8c26a + size: 70323 + timestamp: 1771259521393 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 + md5: a360c33a5abe61c07959e449fa1453eb depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 57821 - timestamp: 1760295480630 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda - sha256: 277dc89950f5d97f1683f26e362d6dca3c2efa16cb2f6fdb73d109effa1cd3d0 - md5: d214916b24c625bcc459b245d509f22e + size: 58592 + timestamp: 1769456073053 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda + sha256: 951958d1792238006fdc6fce7f71f1b559534743b26cc1333497d46e5903a2d6 + md5: 66a0dc7464927d0853b590b6f53ba3ea depends: - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 52573 - timestamp: 1760295626449 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda - sha256: 9b8acdf42df61b7bfe8bdc545c016c29e61985e79748c64ad66df47dbc2e295f - md5: 411ff7cd5d1472bba0f55c0faf04453b + size: 53583 + timestamp: 1769456300951 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + sha256: 6686a26466a527585e6a75cc2a242bf4a3d97d6d6c86424a441677917f28bec7 + md5: 43c04d9cb46ef176bb2a4c77e324d599 depends: - __osx >=11.0 license: MIT license_family: MIT purls: [] - size: 40251 - timestamp: 1760295839166 -- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda - sha256: ddff25aaa4f0aa535413f5d831b04073789522890a4d8626366e43ecde1534a3 - md5: ba4ad812d2afc22b9a34ce8327a0930f + size: 40979 + timestamp: 1769456747661 +- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + sha256: 59d01f2dfa8b77491b5888a5ab88ff4e1574c9359f7e229da254cdfe27ddc190 + md5: 720b39f5ec0610457b725eb3f396219a depends: - ucrt >=10.0.20348.0 - vc >=14.3,<15 @@ -2738,210 +5592,300 @@ packages: license: MIT license_family: MIT purls: [] - size: 44866 - timestamp: 1760295760649 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda - sha256: 08f9b87578ab981c7713e4e6a7d935e40766e10691732bba376d4964562bcb45 - md5: c0374badb3a5d4b1372db28d19462c53 + size: 45831 + timestamp: 1769456418774 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 + md5: 0aa00f03f9e39fb9876085dee11a85d4 depends: - __glibc >=2.17,<3.0.a0 - _openmp_mutex >=4.5 constrains: - - libgomp 15.2.0 h767d61c_7 - - libgcc-ng ==15.2.0=*_7 + - libgcc-ng ==15.2.0=*_18 + - libgomp 15.2.0 he0feb66_18 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 822552 - timestamp: 1759968052178 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda - sha256: 2045066dd8e6e58aaf5ae2b722fb6dfdbb57c862b5f34ac7bfb58c40ef39b6ad - md5: 280ea6eee9e2ddefde25ff799c4f0363 + size: 1041788 + timestamp: 1771378212382 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + sha256: e318a711400f536c81123e753d4c797a821021fb38970cebfb3f454126016893 + md5: d5e96b1ed75ca01906b3d2469b4ce493 depends: - - libgcc 15.2.0 h767d61c_7 + - libgcc 15.2.0 he0feb66_18 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 29313 - timestamp: 1759968065504 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda - sha256: e9fb1c258c8e66ee278397b5822692527c5f5786d372fe7a869b900853f3f5ca - md5: f7b4d76975aac7e5d9e6ad13845f92fe + size: 27526 + timestamp: 1771378224552 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 + md5: 239c5e9546c38a1e884d69effcf4c882 depends: - __glibc >=2.17,<3.0.a0 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 447919 - timestamp: 1759967942498 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - sha256: f2591c0069447bbe28d4d696b7fcb0c5bd0b4ac582769b89addbcf26fb3430d8 - md5: 1a580f7796c7bf6393fddb8bbbde58dc + size: 603262 + timestamp: 1771378117851 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb + md5: c7c83eecbb72d88b940c249af56c8b17 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 constrains: - - xz 5.8.1.* + - xz 5.8.2.* license: 0BSD purls: [] - size: 112894 - timestamp: 1749230047870 -- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda - sha256: 7e22fd1bdb8bf4c2be93de2d4e718db5c548aa082af47a7430eb23192de6bb36 - md5: 8468beea04b9065b9807fc8b9cdc5894 + size: 113207 + timestamp: 1768752626120 +- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda + sha256: 7ab3c98abd3b5d5ec72faa8d9f5d4b50dcee4970ed05339bc381861199dabb41 + md5: 688a0c3d57fa118b9c97bf7e471ab46c depends: - __osx >=10.13 constrains: - - xz 5.8.1.* + - xz 5.8.2.* license: 0BSD purls: [] - size: 104826 - timestamp: 1749230155443 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda - sha256: 0cb92a9e026e7bd4842f410a5c5c665c89b2eb97794ffddba519a626b8ce7285 - md5: d6df911d4564d77c4374b02552cb17d1 + size: 105482 + timestamp: 1768753411348 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda + sha256: 7bfc7ffb2d6a9629357a70d4eadeadb6f88fa26ebc28f606b1c1e5e5ed99dc7e + md5: 009f0d956d7bfb00de86901d16e486c7 depends: - __osx >=11.0 constrains: - - xz 5.8.1.* + - xz 5.8.2.* license: 0BSD purls: [] - size: 92286 - timestamp: 1749230283517 -- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda - sha256: 55764956eb9179b98de7cc0e55696f2eff8f7b83fc3ebff5e696ca358bca28cc - md5: c15148b2e18da456f5108ccb5e411446 + size: 92242 + timestamp: 1768752982486 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda + sha256: f25bf293f550c8ed2e0c7145eb404324611cfccff37660869d97abf526eb957c + md5: ba0bfd4c3cf73f299ffe46ff0eaeb8e3 depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - - xz 5.8.1.* + - xz 5.8.2.* license: 0BSD purls: [] - size: 104935 - timestamp: 1749230611612 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda - sha256: 3aa92d4074d4063f2a162cd8ecb45dccac93e543e565c01a787e16a43501f7ee - md5: c7e925f37e3b40d893459e625f6a53f1 + size: 106169 + timestamp: 1768752763559 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843 + md5: 2c21e66f50753a083cbe6b80f38268fa depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: BSD-2-Clause license_family: BSD purls: [] - size: 91183 - timestamp: 1748393666725 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda - sha256: 98299c73c7a93cd4f5ff8bb7f43cd80389f08b5a27a296d806bdef7841cc9b9e - md5: 18b81186a6adb43f000ad19ed7b70381 + size: 92400 + timestamp: 1769482286018 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda + sha256: 1096c740109386607938ab9f09a7e9bca06d86770a284777586d6c378b8fb3fd + md5: ec88ba8a245855935b871a7324373105 depends: - __osx >=10.13 license: BSD-2-Clause license_family: BSD purls: [] - size: 77667 - timestamp: 1748393757154 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda - sha256: 0a1875fc1642324ebd6c4ac864604f3f18f57fbcf558a8264f6ced028a3c75b2 - md5: 85ccccb47823dd9f7a99d2c7f530342f + size: 79899 + timestamp: 1769482558610 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + sha256: 1089c7f15d5b62c622625ec6700732ece83be8b705da8c6607f4dabb0c4bd6d2 + md5: 57c4be259f5e0b99a5983799a228ae55 depends: - __osx >=11.0 license: BSD-2-Clause license_family: BSD purls: [] - size: 71829 - timestamp: 1748393749336 -- conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda - sha256: fc529fc82c7caf51202cc5cec5bb1c2e8d90edbac6d0a4602c966366efe3c7bf - md5: 74860100b2029e2523cf480804c76b9b + size: 73690 + timestamp: 1769482560514 +- conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + sha256: 40dcd0b9522a6e0af72a9db0ced619176e7cfdb114855c7a64f278e73f8a7514 + md5: e4a9fc2bba3b022dad998c78856afe47 depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: BSD-2-Clause license_family: BSD purls: [] - size: 88657 - timestamp: 1723861474602 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda - sha256: 4c992dcd0e34b68f843e75406f7f303b1b97c248d18f3c7c330bdc0bc26ae0b3 - md5: 729a572a3ebb8c43933b30edcc628ceb + size: 89411 + timestamp: 1769482314283 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + sha256: a4a7dab8db4dc81c736e9a9b42bdfd97b087816e029e221380511960ac46c690 + md5: b499ce4b026493a13774bcf0f4c33849 + depends: + - __glibc >=2.17,<3.0.a0 + - c-ares >=1.34.5,<2.0a0 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.2,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 666600 + timestamp: 1756834976695 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.67.0-h3338091_0.conda + sha256: c48d7e1cc927aef83ff9c48ae34dd1d7495c6ccc1edc4a3a6ba6aff1624be9ac + md5: e7630cef881b1174d40f3e69a883e55f + depends: + - __osx >=10.13 + - c-ares >=1.34.5,<2.0a0 + - libcxx >=19 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.2,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 605680 + timestamp: 1756835898134 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda + sha256: a07cb53b5ffa2d5a18afc6fd5a526a5a53dd9523fbc022148bd2f9395697c46d + md5: a4b4dd73c67df470d091312ab87bf6ae + depends: + - __osx >=11.0 + - c-ares >=1.34.5,<2.0a0 + - libcxx >=19 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.2,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 575454 + timestamp: 1756835746393 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda + sha256: 927fe72b054277cde6cb82597d0fcf6baf127dcbce2e0a9d8925a68f1265eef5 + md5: d864d34357c3b65a4b731f78c0801dc4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-only + license_family: GPL + purls: [] + size: 33731 + timestamp: 1750274110928 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda + sha256: 04596fcee262a870e4b7c9807224680ff48d4d0cc0dac076a602503d3dc6d217 + md5: da5be73701eecd0e8454423fd6ffcf30 depends: - __glibc >=2.17,<3.0.a0 - - icu >=75.1,<76.0a0 + - icu >=78.2,<79.0a0 - libgcc >=14 - libzlib >=1.3.1,<2.0a0 license: blessing purls: [] - size: 945576 - timestamp: 1762299687230 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.0-h86bffb9_0.conda - sha256: ad151af8192c17591fad0b68c9ffb7849ad9f4be9da2020b38b8befd2c5f6f02 - md5: 1ee9b74571acd6dd87e6a0f783989426 + size: 942808 + timestamp: 1768147973361 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda + sha256: 710a7ea27744199023c92e66ad005de7f8db9cf83f10d5a943d786f0dac53b7c + md5: d910105ce2b14dfb2b32e92ec7653420 depends: - __osx >=10.13 - libzlib >=1.3.1,<2.0a0 license: blessing purls: [] - size: 986898 - timestamp: 1762300146976 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.0-h8adb53f_0.conda - sha256: b43d198f147f46866e5336c4a6b91668beef698bfba69d1706158460eadb2c1b - md5: 5fb1945dbc6380e6fe7e939a62267772 + size: 987506 + timestamp: 1768148247615 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda + sha256: 6e9b9f269732cbc4698c7984aa5b9682c168e2a8d1e0406e1ff10091ca046167 + md5: 4b0bf313c53c3e89692f020fb55d5f2c depends: - __osx >=11.0 - - icu >=75.1,<76.0a0 + - icu >=78.2,<79.0a0 - libzlib >=1.3.1,<2.0a0 license: blessing purls: [] - size: 909508 - timestamp: 1762300078624 -- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.0-hf5d6505_0.conda - sha256: 2373bd7450693bd0f624966e1bee2f49b0bf0ffbc114275ed0a43cf35aec5b21 - md5: d2c9300ebd2848862929b18c264d1b1e + size: 909777 + timestamp: 1768148320535 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda + sha256: 756478128e3e104bd7e7c3ce6c1b0efad7e08c7320c69fdc726e039323c63fbb + md5: 903979414b47d777d548e5f0165e6cd8 depends: - ucrt >=10.0.20348.0 - vc >=14.3,<15 - vc14_runtime >=14.44.35208 license: blessing purls: [] - size: 1292710 - timestamp: 1762299749044 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda - sha256: 1b981647d9775e1cdeb2fab0a4dd9cd75a6b0de2963f6c3953dbd712f78334b3 - md5: 5b767048b1b3ee9a954b06f4084f93dc + size: 1291616 + timestamp: 1768148278261 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e + md5: 1b08cd684f34175e4514474793d44bcb depends: - __glibc >=2.17,<3.0.a0 - - libgcc 15.2.0 h767d61c_7 + - libgcc 15.2.0 he0feb66_18 constrains: - - libstdcxx-ng ==15.2.0=*_7 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 3898269 - timestamp: 1759968103436 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda - sha256: 024fd46ac3ea8032a5ec3ea7b91c4c235701a8bf0e6520fe5e6539992a6bd05f - md5: f627678cf829bd70bccf141a19c3ad3e - depends: - - libstdcxx 15.2.0 h8f9b012_7 + - libstdcxx-ng ==15.2.0=*_18 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 29343 - timestamp: 1759968157195 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda - sha256: e5ec6d2ad7eef538ddcb9ea62ad4346fde70a4736342c4ad87bd713641eb9808 - md5: 80c07c68d2f6870250959dcc95b209d1 + size: 5852330 + timestamp: 1771378262446 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda + sha256: 1a7539cfa7df00714e8943e18de0b06cceef6778e420a5ee3a2a145773758aee + md5: db409b7c1720428638e7c0d509d3e1b5 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 license: BSD-3-Clause license_family: BSD purls: [] - size: 37135 - timestamp: 1758626800002 + size: 40311 + timestamp: 1766271528534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + sha256: c180f4124a889ac343fc59d15558e93667d894a966ec6fdb61da1604481be26b + md5: 0f03292cc56bf91a077a134ea8747118 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 895108 + timestamp: 1753948278280 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda + sha256: d90dd0eee6f195a5bd14edab4c5b33be3635b674b0b6c010fb942b956aa2254c + md5: fbfc6cf607ae1e1e498734e256561dc3 + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + purls: [] + size: 422612 + timestamp: 1753948458902 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + sha256: 042c7488ad97a5629ec0a991a8b2a3345599401ecc75ad6a5af73b60e6db9689 + md5: c0d87c3c8e075daf1daf6c31b53e8083 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 421195 + timestamp: 1753948426421 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c + md5: 5aa797f8787fe7a17d1b0821485b5adc + depends: + - libgcc-ng >=12 + license: LGPL-2.1-or-later + purls: [] + size: 100393 + timestamp: 1702724383534 - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 md5: edb0dca6bc32e4f4789199455a1dbeb8 @@ -3028,16 +5972,88 @@ packages: - pytest-cov ; extra == 'test' - lmfit[dev,doc,test] ; extra == 'all' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/d2/f0/834e479e47e499b6478e807fb57b31cc2db696c4db30557bb6f5aea4a90b/mando-0.7.1-py2.py3-none-any.whl + name: mando + version: 0.7.1 + sha256: 26ef1d70928b6057ee3ca12583d73c63e05c49de8972d620c278a7b206581a8a + requires_dist: + - six + - argparse ; python_full_version < '2.7' + - funcsigs ; python_full_version < '3.3' + - rst2ansi ; extra == 'restructuredtext' +- pypi: https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl + name: markdown + version: 3.10.2 + sha256: e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36 + requires_dist: + - coverage ; extra == 'testing' + - pyyaml ; extra == 'testing' + - mkdocs>=1.6 ; extra == 'docs' + - mkdocs-nature>=0.6 ; extra == 'docs' + - mdx-gh-links>=0.2 ; extra == 'docs' + - mkdocstrings[python]>=0.28.3 ; extra == 'docs' + - mkdocs-gen-files ; extra == 'docs' + - mkdocs-section-index ; extra == 'docs' + - mkdocs-literate-nav ; extra == 'docs' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + name: markdown-it-py + version: 4.0.0 + sha256: 87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 + requires_dist: + - mdurl~=0.1 + - psutil ; extra == 'benchmarking' + - pytest ; extra == 'benchmarking' + - pytest-benchmark ; extra == 'benchmarking' + - commonmark~=0.9 ; extra == 'compare' + - markdown~=3.4 ; extra == 'compare' + - mistletoe~=1.0 ; extra == 'compare' + - mistune~=3.0 ; extra == 'compare' + - panflute~=2.3 ; extra == 'compare' + - markdown-it-pyrs ; extra == 'compare' + - linkify-it-py>=1,<3 ; extra == 'linkify' + - mdit-py-plugins>=0.5.0 ; extra == 'plugins' + - gprof2dot ; extra == 'profiling' + - mdit-py-plugins>=0.5.0 ; extra == 'rtd' + - myst-parser ; extra == 'rtd' + - pyyaml ; extra == 'rtd' + - sphinx ; extra == 'rtd' + - sphinx-copybutton ; extra == 'rtd' + - sphinx-design ; extra == 'rtd' + - sphinx-book-theme~=1.0 ; extra == 'rtd' + - jupyter-sphinx ; extra == 'rtd' + - ipykernel ; extra == 'rtd' + - coverage ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + - requests ; extra == 'testing' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl + name: markupsafe + version: 3.0.3 + sha256: 9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl + name: markupsafe + version: 3.0.3 + sha256: 1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: markupsafe version: 3.0.3 - sha256: 9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5 + sha256: 0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl name: markupsafe version: 3.0.3 sha256: e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795 requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl + name: markupsafe + version: 3.0.3 + sha256: de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01 + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl name: markupsafe version: 3.0.3 @@ -3048,10 +6064,91 @@ packages: version: 3.0.3 sha256: ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/02/9c/207547916a02c78f6bdd83448d9b21afbc42f6379ed887ecf610984f3b4e/matplotlib-3.10.7-cp313-cp313-macosx_10_13_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl + name: markupsafe + version: 3.0.3 + sha256: 4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3d/b9/15fd5541ef4f5b9a17eefd379356cf12175fe577424e7b1d80676516031a/matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl + name: matplotlib + version: 3.10.8 + sha256: 3f2e409836d7f5ac2f1c013110a4d50b9f7edc26328c108915f9075d7d7a91b6 + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/64/40/37612487cc8a437d4dd261b32ca21fe2d79510fe74af74e1f42becb1bdb8/matplotlib-3.10.8-cp313-cp313-win_amd64.whl + name: matplotlib + version: 3.10.8 + sha256: e8ea3e2d4066083e264e75c829078f9e149fa119d27e19acd503de65e0b13149 + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/6f/d3/a4bbc01c237ab710a1f22b4da72f4ff6d77eb4c7735ea9811a94ae239067/matplotlib-3.10.8-cp311-cp311-win_amd64.whl + name: matplotlib + version: 3.10.8 + sha256: 18821ace09c763ec93aef5eeff087ee493a24051936d7b9ebcad9662f66501f9 + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: matplotlib + version: 3.10.8 + sha256: a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486 + requires_dist: + - contourpy>=1.0.1 + - cycler>=0.10 + - fonttools>=4.22.0 + - kiwisolver>=1.3.1 + - numpy>=1.23 + - packaging>=20.0 + - pillow>=8 + - pyparsing>=3 + - python-dateutil>=2.7 + - meson-python>=0.13.1,<0.17.0 ; extra == 'dev' + - pybind11>=2.13.2,!=2.13.3 ; extra == 'dev' + - setuptools-scm>=7 ; extra == 'dev' + - setuptools>=64 ; extra == 'dev' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/8d/a0/2ba3473c1b66b9c74dc7107c67e9008cb1782edbe896d4c899d39ae9cf78/matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl name: matplotlib - version: 3.10.7 - sha256: 1d9d3713a237970569156cfb4de7533b7c4eacdd61789726f444f96a0d28f57f + version: 3.10.8 + sha256: 56271f3dac49a88d7fca5060f004d9d22b865f743a12a23b1e937a0be4818ee1 requires_dist: - contourpy>=1.0.1 - cycler>=0.10 @@ -3067,10 +6164,10 @@ packages: - setuptools-scm>=7 ; extra == 'dev' - setuptools>=64 ; extra == 'dev' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/22/ff/6425bf5c20d79aa5b959d1ce9e65f599632345391381c9a104133fe0b171/matplotlib-3.10.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/8f/a0/7024215e95d456de5883e6732e708d8187d9753a21d32f8ddb3befc0c445/matplotlib-3.10.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl name: matplotlib - version: 3.10.7 - sha256: b3c4ea4948d93c9c29dc01c0c23eef66f2101bf75158c291b88de6525c55c3d1 + version: 3.10.8 + sha256: efb30e3baaea72ce5928e32bab719ab4770099079d66726a62b11b1ef7273be4 requires_dist: - contourpy>=1.0.1 - cycler>=0.10 @@ -3086,10 +6183,10 @@ packages: - setuptools-scm>=7 ; extra == 'dev' - setuptools>=64 ; extra == 'dev' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/bc/d0/b3d3338d467d3fc937f0bb7f256711395cae6f78e22cef0656159950adf0/matplotlib-3.10.7-cp313-cp313-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/f8/86/de7e3a1cdcfc941483af70609edc06b83e7c8a0e0dc9ac325200a3f4d220/matplotlib-3.10.8-cp311-cp311-macosx_10_12_x86_64.whl name: matplotlib - version: 3.10.7 - sha256: 37a1fea41153dd6ee061d21ab69c9cf2cf543160b1b85d89cd3d2e2a7902ca4c + version: 3.10.8 + sha256: 6be43b667360fef5c754dda5d25a32e6307a03c204f3c0fc5468b78fa87b4160 requires_dist: - contourpy>=1.0.1 - cycler>=0.10 @@ -3105,10 +6202,10 @@ packages: - setuptools-scm>=7 ; extra == 'dev' - setuptools>=64 ; extra == 'dev' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/e1/b6/23064a96308b9aeceeffa65e96bcde459a2ea4934d311dee20afde7407a0/matplotlib-3.10.7-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/fd/14/baad3222f424b19ce6ad243c71de1ad9ec6b2e4eb1e458a48fdc6d120401/matplotlib-3.10.8-cp311-cp311-macosx_11_0_arm64.whl name: matplotlib - version: 3.10.7 - sha256: 744991e0cc863dd669c8dc9136ca4e6e0082be2070b9d793cbd64bec872a6815 + version: 3.10.8 + sha256: a2b336e2d91a3d7006864e0990c83b216fcdca64b5a6484912902cef87313d78 requires_dist: - contourpy>=1.0.1 - cycler>=0.10 @@ -3136,18 +6233,194 @@ packages: - notebook ; extra == 'test' - pytest ; extra == 'test' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl - name: mccabe - version: 0.7.0 - sha256: 6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e +- pypi: https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl + name: mdit-py-plugins + version: 0.5.0 + sha256: 07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f + requires_dist: + - markdown-it-py>=2.0.0,<5.0.0 + - pre-commit ; extra == 'code-style' + - myst-parser ; extra == 'rtd' + - sphinx-book-theme ; extra == 'rtd' + - coverage ; extra == 'testing' + - pytest ; extra == 'testing' + - pytest-cov ; extra == 'testing' + - pytest-regressions ; extra == 'testing' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl + name: mdurl + version: 0.1.2 + sha256: 84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 + requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl + name: mergedeep + version: 1.3.4 + sha256: 70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307 requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/fd/1a/31b7cd6e4e7a02df4e076162e9783620777592bea9e4bb036389389af99d/mike-2.1.3-py3-none-any.whl + name: mike + version: 2.1.3 + sha256: d90c64077e84f06272437b464735130d380703a76a5738b152932884c60c062a + requires_dist: + - importlib-metadata + - importlib-resources + - jinja2>=2.7 + - mkdocs>=1.0 + - pyparsing>=3.0 + - pyyaml>=5.1 + - pyyaml-env-tag + - verspec + - coverage ; extra == 'dev' + - flake8-quotes ; extra == 'dev' + - flake8>=3.0 ; extra == 'dev' + - shtab ; extra == 'dev' + - coverage ; extra == 'test' + - flake8-quotes ; extra == 'test' + - flake8>=3.0 ; extra == 'test' + - shtab ; extra == 'test' +- pypi: https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl name: mistune - version: 3.1.4 - sha256: 93691da911e5d9d2e23bc54472892aff676df27a75274962ff9edc210364266d + version: 3.2.0 + sha256: febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1 requires_dist: - typing-extensions ; python_full_version < '3.11' requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl + name: mkdocs + version: 1.6.1 + sha256: db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e + requires_dist: + - click>=7.0 + - colorama>=0.4 ; sys_platform == 'win32' + - ghp-import>=1.0 + - importlib-metadata>=4.4 ; python_full_version < '3.10' + - jinja2>=2.11.1 + - markdown>=3.3.6 + - markupsafe>=2.0.1 + - mergedeep>=1.3.4 + - mkdocs-get-deps>=0.2.0 + - packaging>=20.5 + - pathspec>=0.11.1 + - pyyaml-env-tag>=0.1 + - pyyaml>=5.1 + - watchdog>=2.0 + - babel>=2.9.0 ; extra == 'i18n' + - babel==2.9.0 ; extra == 'min-versions' + - click==7.0 ; extra == 'min-versions' + - colorama==0.4 ; sys_platform == 'win32' and extra == 'min-versions' + - ghp-import==1.0 ; extra == 'min-versions' + - importlib-metadata==4.4 ; python_full_version < '3.10' and extra == 'min-versions' + - jinja2==2.11.1 ; extra == 'min-versions' + - markdown==3.3.6 ; extra == 'min-versions' + - markupsafe==2.0.1 ; extra == 'min-versions' + - mergedeep==1.3.4 ; extra == 'min-versions' + - mkdocs-get-deps==0.2.0 ; extra == 'min-versions' + - packaging==20.5 ; extra == 'min-versions' + - pathspec==0.11.1 ; extra == 'min-versions' + - pyyaml-env-tag==0.1 ; extra == 'min-versions' + - pyyaml==5.1 ; extra == 'min-versions' + - watchdog==2.0 ; extra == 'min-versions' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl + name: mkdocs-autorefs + version: 1.4.4 + sha256: 834ef5408d827071ad1bc69e0f39704fa34c7fc05bc8e1c72b227dfdc5c76089 + requires_dist: + - markdown>=3.3 + - markupsafe>=2.0.1 + - mkdocs>=1.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl + name: mkdocs-get-deps + version: 0.2.0 + sha256: 2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134 + requires_dist: + - importlib-metadata>=4.3 ; python_full_version < '3.10' + - mergedeep>=1.3.4 + - platformdirs>=2.2.0 + - pyyaml>=5.1 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/08/37/5f1fd5c3f6954b3256f8126275e62af493b96fb6aef6c0dbc4ee326032ad/mkdocs_jupyter-0.25.1-py3-none-any.whl + name: mkdocs-jupyter + version: 0.25.1 + sha256: 3f679a857609885d322880e72533ef5255561bbfdb13cfee2a1e92ef4d4ad8d8 + requires_dist: + - ipykernel>6.0.0,<7.0.0 + - jupytext>1.13.8,<2 + - mkdocs-material>9.0.0 + - mkdocs>=1.4.0,<2 + - nbconvert>=7.2.9,<8 + - pygments>2.12.0 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a8/4e/c09876f08fa9faaa5e1178f3d77b7af3f343258689bd6f3b72593b2f74e3/mkdocs_markdownextradata_plugin-0.2.6-py3-none-any.whl + name: mkdocs-markdownextradata-plugin + version: 0.2.6 + sha256: 34dd40870781784c75809596b2d8d879da783815b075336d541de1f150c94242 + requires_dist: + - mkdocs + - pyyaml + requires_python: '>=3.6' +- pypi: https://files.pythonhosted.org/packages/b9/1b/16ad0193079bb8a15aa1d2620813a9cd15b18de150a4ea1b2c607fb4c74d/mkdocs_material-9.7.3-py3-none-any.whl + name: mkdocs-material + version: 9.7.3 + sha256: 37ebf7b4788c992203faf2e71900be3c197c70a4be9b0d72aed537b08a91dd9d + requires_dist: + - babel>=2.10 + - backrefs>=5.7.post1 + - colorama>=0.4 + - jinja2>=3.1 + - markdown>=3.2 + - mkdocs-material-extensions>=1.3 + - mkdocs>=1.6 + - paginate>=0.5 + - pygments>=2.16 + - pymdown-extensions>=10.2 + - requests>=2.30 + - mkdocs-git-committers-plugin-2>=1.1 ; extra == 'git' + - mkdocs-git-revision-date-localized-plugin>=1.2.4 ; extra == 'git' + - cairosvg>=2.6 ; extra == 'imaging' + - pillow>=10.2 ; extra == 'imaging' + - mkdocs-minify-plugin>=0.7 ; extra == 'recommended' + - mkdocs-redirects>=1.2 ; extra == 'recommended' + - mkdocs-rss-plugin>=1.6 ; extra == 'recommended' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl + name: mkdocs-material-extensions + version: 1.3.1 + sha256: adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/c6/3d/020a6b6248c3d4a37797db068256f0b3f15b01bc481327ba888c50309aa8/mkdocs_plugin_inline_svg-0.1.0-py3-none-any.whl + name: mkdocs-plugin-inline-svg + version: 0.1.0 + sha256: a5aab2d98a19b24019f8e650f54fc647c2f31e7d0e36fc5cf2d2161acc0ea49a + requires_dist: + - mkdocs + requires_python: '>=3.5' +- pypi: https://files.pythonhosted.org/packages/04/41/1cf02e3df279d2dd846a1bf235a928254eba9006dd22b4a14caa71aed0f7/mkdocstrings-1.0.3-py3-none-any.whl + name: mkdocstrings + version: 1.0.3 + sha256: 0d66d18430c2201dc7fe85134277382baaa15e6b30979f3f3bdbabd6dbdb6046 + requires_dist: + - jinja2>=3.1 + - markdown>=3.6 + - markupsafe>=1.1 + - mkdocs>=1.6 + - mkdocs-autorefs>=1.4 + - pymdown-extensions>=6.3 + - mkdocstrings-crystal>=0.3.4 ; extra == 'crystal' + - mkdocstrings-python-legacy>=0.2.1 ; extra == 'python-legacy' + - mkdocstrings-python>=1.16.2 ; extra == 'python' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl + name: mkdocstrings-python + version: 2.0.3 + sha256: 0b83513478bdfd803ff05aa43e9b1fca9dd22bcd9471f09ca6257f009bc5ee12 + requires_dist: + - mkdocstrings>=0.30 + - mkdocs-autorefs>=1.4 + - griffelib>=2.0 + - typing-extensions>=4.0 ; python_full_version < '3.11' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/5b/69/93b34728cc386efdde0c342f8c680b9187dea7beb7adaf6b58a0713be101/mpld3-0.5.12-py3-none-any.whl name: mpld3 version: 0.5.12 @@ -3155,6 +6428,16 @@ packages: requires_dist: - jinja2 - matplotlib +- pypi: https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl + name: msgpack + version: 1.1.2 + sha256: d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/2c/97/560d11202bcd537abca693fd85d81cebe2107ba17301de42b01ac1677b69/msgpack-1.1.2-cp311-cp311-macosx_10_9_x86_64.whl + name: msgpack + version: 1.1.2 + sha256: 2e86a607e558d22985d856948c12a3fa7b42efad264dca8a3ebbcfa2735d786c + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: msgpack version: 1.1.2 @@ -3170,45 +6453,155 @@ packages: version: 1.1.2 sha256: a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9 requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/83/04/28a41024ccbd67467380b6fb440ae916c1e4f25e2cd4c63abe6835ac566e/msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl + name: msgpack + version: 1.1.2 + sha256: 283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0 + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl name: msgpack version: 1.1.2 sha256: 42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: msgpack + version: 1.1.2 + sha256: 454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/03/59/fdcb3af72f750a8de2bcf39d62ada70b5eb17b06d7f63860e0a679cb656b/msgspec-0.20.0-cp311-cp311-macosx_10_9_x86_64.whl + name: msgspec + version: 0.20.0 + sha256: 09e0efbf1ac641fedb1d5496c59507c2f0dc62a052189ee62c763e0aae217520 + requires_dist: + - tomli ; python_full_version < '3.11' and extra == 'toml' + - tomli-w ; extra == 'toml' + - pyyaml ; extra == 'yaml' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/28/83/36557b04cfdc317ed8a525c4993b23e43a8fbcddaddd78619112ca07138c/msgspec-0.20.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: msgspec + version: 0.20.0 + sha256: 7fac7e9c92eddcd24c19d9e5f6249760941485dff97802461ae7c995a2450111 + requires_dist: + - tomli ; python_full_version < '3.11' and extra == 'toml' + - tomli-w ; extra == 'toml' + - pyyaml ; extra == 'yaml' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/57/b6/eff0305961a1d9447ec2b02f8c73c8946f22564d302a504185b730c9a761/msgspec-0.20.0-cp313-cp313-macosx_11_0_arm64.whl + name: msgspec + version: 0.20.0 + sha256: f6532369ece217fd37c5ebcfd7e981f2615628c21121b7b2df9d3adcf2fd69b8 + requires_dist: + - tomli ; python_full_version < '3.11' and extra == 'toml' + - tomli-w ; extra == 'toml' + - pyyaml ; extra == 'yaml' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/5a/15/3c225610da9f02505d37d69a77f4a2e7daae2a125f99d638df211ba84e59/msgspec-0.20.0-cp311-cp311-macosx_11_0_arm64.whl + name: msgspec + version: 0.20.0 + sha256: 23ee3787142e48f5ee746b2909ce1b76e2949fbe0f97f9f6e70879f06c218b54 + requires_dist: + - tomli ; python_full_version < '3.11' and extra == 'toml' + - tomli-w ; extra == 'toml' + - pyyaml ; extra == 'yaml' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/6b/96/5c095b940de3aa6b43a71ec76275ac3537b21bd45c7499b5a17a429110fa/msgspec-0.20.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: msgspec + version: 0.20.0 + sha256: bb4d873f24ae18cd1334f4e37a178ed46c9d186437733351267e0a269bdf7e53 + requires_dist: + - tomli ; python_full_version < '3.11' and extra == 'toml' + - tomli-w ; extra == 'toml' + - pyyaml ; extra == 'yaml' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/89/5e/406b7d578926b68790e390d83a1165a9bfc2d95612a1a9c1c4d5c72ea815/msgspec-0.20.0-cp311-cp311-win_amd64.whl + name: msgspec + version: 0.20.0 + sha256: d1dcc93a3ce3d3195985bfff18a48274d0b5ffbc96fa1c5b89da6f0d9af81b29 + requires_dist: + - tomli ; python_full_version < '3.11' and extra == 'toml' + - tomli-w ; extra == 'toml' + - pyyaml ; extra == 'yaml' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/8a/d1/b902d38b6e5ba3bdddbec469bba388d647f960aeed7b5b3623a8debe8a76/msgspec-0.20.0-cp313-cp313-macosx_10_13_x86_64.whl + name: msgspec + version: 0.20.0 + sha256: 9c1ff8db03be7598b50dd4b4a478d6fe93faae3bd54f4f17aa004d0e46c14c46 + requires_dist: + - tomli ; python_full_version < '3.11' and extra == 'toml' + - tomli-w ; extra == 'toml' + - pyyaml ; extra == 'yaml' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/f1/25/5e8080fe0117f799b1b68008dc29a65862077296b92550632de015128579/msgspec-0.20.0-cp313-cp313-win_amd64.whl + name: msgspec + version: 0.20.0 + sha256: 67d5e4dfad52832017018d30a462604c80561aa62a9d548fc2bd4e430b66a352 + requires_dist: + - tomli ; python_full_version < '3.11' and extra == 'toml' + - tomli-w ; extra == 'toml' + - pyyaml ; extra == 'yaml' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/5a/56/21b27c560c13822ed93133f08aa6372c53a8e067f11fbed37b4adcdac922/multidict-6.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: multidict + version: 6.7.1 + sha256: 439cbebd499f92e9aa6793016a8acaa161dfa749ae86d20960189f5398a19144 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl + name: multidict + version: 6.7.1 + sha256: 935434b9853c7c112eee7ac891bc4cb86455aa631269ae35442cb316790c1445 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/a6/9b/267e64eaf6fc637a15b35f5de31a566634a2740f97d8d094a69d34f524a4/multidict-6.7.1-cp311-cp311-macosx_10_9_x86_64.whl + name: multidict + version: 6.7.1 + sha256: 844c5bca0b5444adb44a623fb0a1310c2f4cd41f402126bb269cd44c9b3f3e1e + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: multidict + version: 6.7.1 + sha256: 9d624335fd4fa1c08a53f8b4be7676ebde19cd092b3895c421045ca87895b429 + requires_dist: + - typing-extensions>=4.1.0 ; python_full_version < '3.11' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl name: multidict - version: 6.7.0 - sha256: 30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390 + version: 6.7.1 + sha256: 960c83bf01a95b12b08fd54324a4eb1d5b52c88932b5cba5d6e712bb3ed12eb5 requires_dist: - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/c7/75/bc704ae15fee974f8fccd871305e254754167dce5f9e42d88a2def741a1d/multidict-6.7.1-cp313-cp313-macosx_10_13_x86_64.whl name: multidict - version: 6.7.0 - sha256: 7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159 + version: 6.7.1 + sha256: 84e61e3af5463c19b67ced91f6c634effb89ef8bfc5ca0267f954451ed4bb6a2 requires_dist: - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/c9/68/f16a3a8ba6f7b6dc92a1f19669c0810bd2c43fc5a02da13b1cbf8e253845/multidict-6.7.1-cp311-cp311-win_amd64.whl name: multidict - version: 6.7.0 - sha256: 9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32 + version: 6.7.1 + sha256: bdbf9f3b332abd0cdb306e7c2113818ab1e922dc84b8f8fd06ec89ed2a19ab8b requires_dist: - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/dd/a4/d45caf2b97b035c57267791ecfaafbd59c68212004b3842830954bb4b02e/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl name: multidict - version: 6.7.0 - sha256: 9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca + version: 6.7.1 + sha256: f2a0a924d4c2e9afcd7ec64f9de35fcd96915149b2216e1cb2c10a56df483855 requires_dist: - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0b/9a/c6f79de7ba3a0a8473129936b7b90aa461d3d46fec6f1627672b1dccf4e9/narwhals-2.12.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl name: narwhals - version: 2.12.0 - sha256: baeba5d448a30b04c299a696bd9ee5ff73e4742143e06c49ca316b46539a7cbb + version: 2.17.0 + sha256: 2ac5307b7c2b275a7d66eeda906b8605e3d7a760951e188dcfff86e8ebe083dd requires_dist: - - cudf>=24.10.0 ; extra == 'cudf' + - cudf-cu12>=24.10.0 ; extra == 'cudf' - dask[dataframe]>=2024.8 ; extra == 'dask' - duckdb>=1.1 ; extra == 'duckdb' - ibis-framework>=6.0.0 ; extra == 'ibis' @@ -3221,16 +6614,18 @@ packages: - pyarrow>=13.0.0 ; extra == 'pyarrow' - pyspark>=3.5.0 ; extra == 'pyspark' - pyspark[connect]>=3.5.0 ; extra == 'pyspark-connect' + - duckdb>=1.1 ; extra == 'sql' + - sqlparse ; extra == 'sql' - sqlframe>=3.22.0,!=3.39.3 ; extra == 'sqlframe' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl name: nbclient - version: 0.10.2 - sha256: 4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d + version: 0.10.4 + sha256: 9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440 requires_dist: - jupyter-client>=6.1.12 - jupyter-core>=4.12,!=5.0.* - - nbformat>=5.1 + - nbformat>=5.1.3 - traitlets>=5.4 - pre-commit ; extra == 'dev' - autodoc-traits ; extra == 'docs' @@ -3242,9 +6637,9 @@ packages: - moto ; extra == 'docs' - myst-parser ; extra == 'docs' - nbconvert>=7.1.0 ; extra == 'docs' - - pytest-asyncio ; extra == 'docs' + - pytest-asyncio>=1.3.0 ; extra == 'docs' - pytest-cov>=4.0 ; extra == 'docs' - - pytest>=7.0,<8 ; extra == 'docs' + - pytest>=9.0.1,<10 ; extra == 'docs' - sphinx-book-theme ; extra == 'docs' - sphinx>=1.7 ; extra == 'docs' - sphinxcontrib-spelling ; extra == 'docs' @@ -3255,16 +6650,16 @@ packages: - ipython ; extra == 'test' - ipywidgets ; extra == 'test' - nbconvert>=7.1.0 ; extra == 'test' - - pytest-asyncio ; extra == 'test' + - pytest-asyncio>=1.3.0 ; extra == 'test' - pytest-cov>=4.0 ; extra == 'test' - - pytest>=7.0,<8 ; extra == 'test' + - pytest>=9.0.1,<10 ; extra == 'test' - testpath ; extra == 'test' - xmltodict ; extra == 'test' - requires_python: '>=3.9.0' -- pypi: https://files.pythonhosted.org/packages/cc/9a/cd673b2f773a12c992f41309ef81b99da1690426bd2f96957a7ade0d3ed7/nbconvert-7.16.6-py3-none-any.whl + requires_python: '>=3.10.0' +- pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl name: nbconvert - version: 7.16.6 - sha256: 1375a7b67e0c2883678c48e506dc320febb57685e5ee67faa51b18a90f3a712b + version: 7.17.0 + sha256: 4f99a63b337b9a23504347afdab24a11faa7d86b405e5c8f9881cd313336d518 requires_dist: - beautifulsoup4 - bleach[css]!=5.0.0 @@ -3282,6 +6677,7 @@ packages: - pygments>=2.4.1 - traitlets>=5.1 - flaky ; extra == 'all' + - intersphinx-registry ; extra == 'all' - ipykernel ; extra == 'all' - ipython ; extra == 'all' - ipywidgets>=7.5 ; extra == 'all' @@ -3291,15 +6687,16 @@ packages: - pydata-sphinx-theme ; extra == 'all' - pyqtwebengine>=5.15 ; extra == 'all' - pytest>=7 ; extra == 'all' - - sphinx==5.0.2 ; extra == 'all' + - sphinx>=5.0.2 ; extra == 'all' - sphinxcontrib-spelling ; extra == 'all' - tornado>=6.1 ; extra == 'all' + - intersphinx-registry ; extra == 'docs' - ipykernel ; extra == 'docs' - ipython ; extra == 'docs' - myst-parser ; extra == 'docs' - nbsphinx>=0.2.12 ; extra == 'docs' - pydata-sphinx-theme ; extra == 'docs' - - sphinx==5.0.2 ; extra == 'docs' + - sphinx>=5.0.2 ; extra == 'docs' - sphinxcontrib-spelling ; extra == 'docs' - pyqtwebengine>=5.15 ; extra == 'qtpdf' - pyqtwebengine>=5.15 ; extra == 'qtpng' @@ -3309,7 +6706,7 @@ packages: - ipywidgets>=7.5 ; extra == 'test' - pytest>=7 ; extra == 'test' - playwright ; extra == 'webpdf' - requires_python: '>=3.8' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl name: nbformat version: 5.10.4 @@ -3329,6 +6726,43 @@ packages: - pytest ; extra == 'test' - testpath ; extra == 'test' requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/eb/be/b257e12f9710819fde40adc972578bee6b72c5992da1bc8369bef2597756/nbmake-1.5.5-py3-none-any.whl + name: nbmake + version: 1.5.5 + sha256: c6fbe6e48b60cacac14af40b38bf338a3b88f47f085c54ac5b8639ff0babaf4b + requires_dist: + - ipykernel>=5.4.0 + - nbclient>=0.6.6 + - nbformat>=5.0.4 + - pygments>=2.7.3 + - pytest>=6.1.0 + requires_python: '>=3.8.0' +- pypi: https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl + name: nbqa + version: 1.9.1 + sha256: 95552d2f6c2c038136252a805aa78d85018aef922586270c3a074332737282e5 + requires_dist: + - autopep8>=1.5 + - ipython>=7.8.0 + - tokenize-rt>=3.2.0 + - tomli + - black ; extra == 'toolchain' + - blacken-docs ; extra == 'toolchain' + - flake8 ; extra == 'toolchain' + - isort ; extra == 'toolchain' + - jupytext ; extra == 'toolchain' + - mypy ; extra == 'toolchain' + - pylint ; extra == 'toolchain' + - pyupgrade ; extra == 'toolchain' + - ruff ; extra == 'toolchain' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/20/16/e777eadfa0c0305878c36fae1d5e6db474fbb15dae202b9ec378809dfb4d/nbstripout-0.9.1-py3-none-any.whl + name: nbstripout + version: 0.9.1 + sha256: ca027ee45742ee77e4f8e9080254f9a707f1161ba11367b82fdf4a29892c759e + requires_dist: + - nbformat + requires_python: '>=3.10' - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 md5: 47e340acb35de30501a76c7c799c41d7 @@ -3362,21 +6796,92 @@ packages: version: 1.6.0 sha256: 87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c requires_python: '>=3.5' -- pypi: https://files.pythonhosted.org/packages/42/0f/c76bf3dba22c73c38e9b1113b017cf163f7696f50e003404ec5ecdb1e8a6/nh3-0.3.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: nh3 - version: 0.3.2 - sha256: 7bb18403f02b655a1bbe4e3a4696c2ae1d6ae8f5991f7cacb684b1ae27e6c9f7 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/64/9a/1a1c154f10a575d20dd634e5697805e589bbdb7673a0ad00e8da90044ba7/nh3-0.3.2-cp38-abi3-win_amd64.whl - name: nh3 - version: 0.3.2 - sha256: 562da3dca7a17f9077593214a9781a94b8d76de4f158f8c895e62f09573945fe - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/b6/3e/f5a5cc2885c24be13e9b937441bd16a012ac34a657fe05e58927e8af8b7a/nh3-0.3.2-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl - name: nh3 - version: 0.3.2 - sha256: 7064ccf5ace75825bd7bf57859daaaf16ed28660c1c6b306b649a9eda4b54b1e - requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl + name: nodeenv + version: 1.10.0 + sha256: 5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*' +- conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.7.0-he4ff34a_0.conda + sha256: 4791285a34195615e22a94dc62cbd43181548b34eb34e6cb1dcf8f469476a32e + md5: ba562095149fde99c700365d90e6d632 + depends: + - __glibc >=2.28,<3.0.a0 + - libstdcxx >=14 + - libgcc >=14 + - libnghttp2 >=1.67.0,<2.0a0 + - c-ares >=1.34.6,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + - libbrotlicommon >=1.2.0,<1.3.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + - libuv >=1.51.0,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - libabseil >=20260107.1,<20260108.0a0 + - libabseil * cxx17* + - icu >=78.2,<79.0a0 + - libzlib >=1.3.1,<2.0a0 + - libsqlite >=3.51.2,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 18875002 + timestamp: 1772300115686 +- conda: https://conda.anaconda.org/conda-forge/osx-64/nodejs-25.7.0-hf6efa0e_0.conda + sha256: a23a3b536f1ccd3c10a2cbdf8c638b601c51f6e9bbf1e6c708610cf5b1df3d0f + md5: 448185eb18358e4b5fe2a157cc7e415f + depends: + - libcxx >=19 + - __osx >=10.15 + - openssl >=3.5.5,<4.0a0 + - c-ares >=1.34.6,<2.0a0 + - libuv >=1.51.0,<2.0a0 + - libbrotlicommon >=1.2.0,<1.3.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + - libabseil >=20260107.1,<20260108.0a0 + - libabseil * cxx17* + - libnghttp2 >=1.67.0,<2.0a0 + - icu >=78.2,<79.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: MIT + license_family: MIT + purls: [] + size: 18342335 + timestamp: 1772299132495 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-25.7.0-hbfc8e16_0.conda + sha256: 6398a45d2bb943585540d98a9b1b3bed1fb48fabd327b56eba2ece00e3dd202f + md5: 22a4a51f30590f274bb3f831d911c09a + depends: + - __osx >=11.0 + - libcxx >=19 + - libsqlite >=3.51.2,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + - libbrotlicommon >=1.2.0,<1.3.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + - libuv >=1.51.0,<2.0a0 + - libabseil >=20260107.1,<20260108.0a0 + - libabseil * cxx17* + - icu >=78.2,<79.0a0 + - c-ares >=1.34.6,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - libnghttp2 >=1.67.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 17351648 + timestamp: 1772299122966 +- conda: https://conda.anaconda.org/conda-forge/win-64/nodejs-25.7.0-h80d1838_0.conda + sha256: 0ea0ddad32366396d1beda7ce93ddd3d9f705286c1a4f99f05ec0049183c1e97 + md5: 61b62d3be12c9edbe34f202d51891927 + license: MIT + license_family: MIT + purls: [] + size: 31254428 + timestamp: 1772299132945 - pypi: https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl name: notebook-shim version: 0.2.4 @@ -3388,29 +6893,49 @@ packages: - pytest-jupyter ; extra == 'test' - pytest-tornasync ; extra == 'test' requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/04/dc/46066ce18d01645541f0186877377b9371b8fa8017fa8262002b4ef22612/numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: numpy + version: 2.4.2 + sha256: d0d9b7c93578baafcbc5f0b83eaf17b79d345c6f36917ba0c67f45226911d499 + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/09/f0/817d03a03f93ba9c6c8993de509277d84e69f9453601915e4a69554102a1/numpy-2.4.2-cp313-cp313-macosx_11_0_arm64.whl name: numpy - version: 2.3.5 - sha256: 00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b + version: 2.4.2 + sha256: bd3a7a9f5847d2fb8c2c6d1c862fa109c31a9abeca1a3c2bd5a64572955b2979 requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/1b/46/6fa4ea94f1ddf969b2ee941290cca6f1bfac92b53c76ae5f44afe17ceb69/numpy-2.4.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl name: numpy - version: 2.3.5 - sha256: aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188 + version: 2.4.2 + sha256: c02ef4401a506fb60b411467ad501e1429a3487abca4664871d9ae0b46c8ba32 requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/43/bc/6352f343522fcb2c04dbaf94cb30cca6fd32c1a750c06ad6231b4293708c/numpy-2.4.2-cp313-cp313-win_amd64.whl name: numpy - version: 2.3.5 - sha256: d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff + version: 2.4.2 + sha256: 7df2de1e4fba69a51c06c28f5a3de36731eb9639feb8e1cf7e4a7b0daf4cf622 requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/74/41/5d17d4058bd0cd96bcbd4d9ff0fb2e21f52702aab9a72e4a594efa18692f/numpy-2.4.2-cp311-cp311-macosx_11_0_arm64.whl name: numpy - version: 2.3.5 - sha256: 11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017 + version: 2.4.2 + sha256: 7edc794af8b36ca37ef5fcb5e0d128c7e0595c7b96a2318d1badb6fcd8ee86b1 requires_python: '>=3.11' -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda - sha256: a47271202f4518a484956968335b2521409c8173e123ab381e775c358c67fe6d - md5: 9ee58d5c534af06558933af3c845a780 +- pypi: https://files.pythonhosted.org/packages/76/ae/e0265e0163cf127c24c3969d29f1c4c64551a1e375d95a13d32eab25d364/numpy-2.4.2-cp311-cp311-win_amd64.whl + name: numpy + version: 2.4.2 + sha256: b9c618d56a29c9cb1c4da979e9899be7578d2e0b3c24d52079c166324c9e8695 + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/a1/22/815b9fe25d1d7ae7d492152adbc7226d3eff731dffc38fe970589fcaaa38/numpy-2.4.2-cp313-cp313-macosx_10_13_x86_64.whl + name: numpy + version: 2.4.2 + sha256: 25f2059807faea4b077a2b6837391b5d830864b3543627f381821c646f31a63c + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/d3/44/71852273146957899753e69986246d6a176061ea183407e95418c2aa4d9a/numpy-2.4.2-cp311-cp311-macosx_10_9_x86_64.whl + name: numpy + version: 2.4.2 + sha256: e7e88598032542bd49af7c4747541422884219056c268823ef6e5e89851c8825 + requires_python: '>=3.11' +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda + sha256: 44c877f8af015332a5d12f5ff0fb20ca32f896526a7d0cdb30c769df1144fb5c + md5: f61eb8cd60ff9057122a3d338b99c00f depends: - __glibc >=2.17,<3.0.a0 - ca-certificates @@ -3418,33 +6943,33 @@ packages: license: Apache-2.0 license_family: Apache purls: [] - size: 3165399 - timestamp: 1762839186699 -- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda - sha256: 36fe9fb316be22fcfb46d5fa3e2e85eec5ef84f908b7745f68f768917235b2d5 - md5: 3f50cdf9a97d0280655758b735781096 + size: 3164551 + timestamp: 1769555830639 +- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda + sha256: e02e5639b0e4d6d4fcf0f3b082642844fb5a37316f5b0a1126c6271347462e90 + md5: 30bb8d08b99b9a7600d39efb3559fff0 depends: - __osx >=10.13 - ca-certificates license: Apache-2.0 license_family: Apache purls: [] - size: 2778996 - timestamp: 1762840724922 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda - sha256: ebe93dafcc09e099782fe3907485d4e1671296bc14f8c383cb6f3dfebb773988 - md5: b34dc4172653c13dcf453862f251af2b + size: 2777136 + timestamp: 1769557662405 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda + sha256: 361f5c5e60052abc12bdd1b50d7a1a43e6a6653aab99a2263bf2288d709dcf67 + md5: f4f6ad63f98f64191c3e77c5f5f29d76 depends: - __osx >=11.0 - ca-certificates license: Apache-2.0 license_family: Apache purls: [] - size: 3108371 - timestamp: 1762839712322 -- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda - sha256: 6d72d6f766293d4f2aa60c28c244c8efed6946c430814175f959ffe8cab899b3 - md5: 84f8fb4afd1157f59098f618cd2437e4 + size: 3104268 + timestamp: 1769556384749 +- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda + sha256: 53a5ad2e5553b8157a91bb8aa375f78c5958f77cb80e9d2ce59471ea8e5c0bd6 + md5: eb585509b815415bc964b2c7e11c7eb3 depends: - ca-certificates - ucrt >=10.0.20348.0 @@ -3453,408 +6978,913 @@ packages: license: Apache-2.0 license_family: Apache purls: [] - size: 9440812 - timestamp: 1762841722179 -- pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl + size: 9343023 + timestamp: 1769557547888 +- pypi: https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl + name: overrides + version: 7.7.0 + sha256: c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49 + requires_dist: + - typing ; python_full_version < '3.5' + requires_python: '>=3.6' +- pypi: https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl name: packaging - version: '25.0' - sha256: 29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 + version: '26.0' + sha256: b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl + name: paginate + version: 0.5.7 + sha256: b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591 + requires_dist: + - pytest ; extra == 'dev' + - tox ; extra == 'dev' + - black ; extra == 'lint' +- pypi: https://files.pythonhosted.org/packages/0b/48/aad6ec4f8d007534c091e9a7172b3ec1b1ee6d99a9cbb936b5eab6c6cf58/pandas-3.0.1-cp313-cp313-macosx_10_13_x86_64.whl + name: pandas + version: 3.0.1 + sha256: 5272627187b5d9c20e55d27caf5f2cd23e286aba25cadf73c8590e432e2b7262 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/1f/67/af63f83cd6ca603a00fe8530c10a60f0879265b8be00b5930e8e78c5b30b/pandas-3.0.1-cp311-cp311-win_amd64.whl + name: pandas + version: 3.0.1 + sha256: 84f0904a69e7365f79a0c77d3cdfccbfb05bf87847e3a51a41e1426b0edb9c79 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/2e/7c/870c7e7daec2a6c7ff2ac9e33b23317230d4e4e954b35112759ea4a924a7/pandas-3.0.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: pandas + version: 3.0.1 + sha256: 830994d7e1f31dd7e790045235605ab61cff6c94defc774547e8b7fdfbff3dc7 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/a8/14/5990826f779f79148ae9d3a2c39593dc04d61d5d90541e71b5749f35af95/pandas-3.0.1-cp313-cp313-macosx_11_0_arm64.whl + name: pandas + version: 3.0.1 + sha256: 661e0f665932af88c7877f31da0dc743fe9c8f2524bdffe23d24fdcb67ef9d56 + requires_dist: + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' + - python-dateutil>=2.8.2 + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' + - pyxlsb>=1.0.10 ; extra == 'excel' + - xlrd>=2.0.1 ; extra == 'excel' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' + - html5lib>=1.1 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' + - tabulate>=0.9.0 ; extra == 'output-formatting' + - pyqt5>=5.15.9 ; extra == 'clipboard' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' + - html5lib>=1.1 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' + - odfpy>=1.4.1 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' + - pyqt5>=5.15.9 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' + - pyxlsb>=1.0.10 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' + - xlrd>=2.0.1 ; extra == 'all' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/c1/27/90683c7122febeefe84a56f2cde86a9f05f68d53885cebcc473298dfc33e/pandas-3.0.1-cp311-cp311-macosx_11_0_arm64.whl name: pandas - version: 2.3.3 - sha256: 318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac + version: 3.0.1 + sha256: 24ba315ba3d6e5806063ac6eb717504e499ce30bd8c236d8693a5fd3f084c796 requires_dist: - - numpy>=1.22.4 ; python_full_version < '3.11' - - numpy>=1.23.2 ; python_full_version == '3.11.*' - - numpy>=1.26.0 ; python_full_version >= '3.12' + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' - python-dateutil>=2.8.2 - - pytz>=2020.1 - - tzdata>=2022.7 - - hypothesis>=6.46.1 ; extra == 'test' - - pytest>=7.3.2 ; extra == 'test' - - pytest-xdist>=2.2.0 ; extra == 'test' - - pyarrow>=10.0.1 ; extra == 'pyarrow' - - bottleneck>=1.3.6 ; extra == 'performance' - - numba>=0.56.4 ; extra == 'performance' - - numexpr>=2.8.4 ; extra == 'performance' - - scipy>=1.10.0 ; extra == 'computation' - - xarray>=2022.12.0 ; extra == 'computation' - - fsspec>=2022.11.0 ; extra == 'fss' - - s3fs>=2022.11.0 ; extra == 'aws' - - gcsfs>=2022.11.0 ; extra == 'gcp' - - pandas-gbq>=0.19.0 ; extra == 'gcp' + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.0 ; extra == 'excel' - - python-calamine>=0.1.7 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' - pyxlsb>=1.0.10 ; extra == 'excel' - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.0.5 ; extra == 'excel' - - pyarrow>=10.0.1 ; extra == 'parquet' - - pyarrow>=10.0.1 ; extra == 'feather' - - tables>=3.8.0 ; extra == 'hdf5' - - pyreadstat>=1.2.0 ; extra == 'spss' - - sqlalchemy>=2.0.0 ; extra == 'postgresql' - - psycopg2>=2.9.6 ; extra == 'postgresql' - - adbc-driver-postgresql>=0.8.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.0 ; extra == 'mysql' - - pymysql>=1.0.2 ; extra == 'mysql' - - sqlalchemy>=2.0.0 ; extra == 'sql-other' - - adbc-driver-postgresql>=0.8.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=0.8.0 ; extra == 'sql-other' - - beautifulsoup4>=4.11.2 ; extra == 'html' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' - html5lib>=1.1 ; extra == 'html' - - lxml>=4.9.2 ; extra == 'html' - - lxml>=4.9.2 ; extra == 'xml' - - matplotlib>=3.6.3 ; extra == 'plot' - - jinja2>=3.1.2 ; extra == 'output-formatting' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' - tabulate>=0.9.0 ; extra == 'output-formatting' - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.3.0 ; extra == 'clipboard' - - zstandard>=0.19.0 ; extra == 'compression' - - dataframe-api-compat>=0.1.7 ; extra == 'consortium-standard' - - adbc-driver-postgresql>=0.8.0 ; extra == 'all' - - adbc-driver-sqlite>=0.8.0 ; extra == 'all' - - beautifulsoup4>=4.11.2 ; extra == 'all' - - bottleneck>=1.3.6 ; extra == 'all' - - dataframe-api-compat>=0.1.7 ; extra == 'all' - - fastparquet>=2022.12.0 ; extra == 'all' - - fsspec>=2022.11.0 ; extra == 'all' - - gcsfs>=2022.11.0 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.46.1 ; extra == 'all' - - jinja2>=3.1.2 ; extra == 'all' - - lxml>=4.9.2 ; extra == 'all' - - matplotlib>=3.6.3 ; extra == 'all' - - numba>=0.56.4 ; extra == 'all' - - numexpr>=2.8.4 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.0 ; extra == 'all' - - pandas-gbq>=0.19.0 ; extra == 'all' - - psycopg2>=2.9.6 ; extra == 'all' - - pyarrow>=10.0.1 ; extra == 'all' - - pymysql>=1.0.2 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.0 ; extra == 'all' - - pytest>=7.3.2 ; extra == 'all' - - pytest-xdist>=2.2.0 ; extra == 'all' - - python-calamine>=0.1.7 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.3.0 ; extra == 'all' - - scipy>=1.10.0 ; extra == 'all' - - s3fs>=2022.11.0 ; extra == 'all' - - sqlalchemy>=2.0.0 ; extra == 'all' - - tables>=3.8.0 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2022.12.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.0.5 ; extra == 'all' - - zstandard>=0.19.0 ; extra == 'all' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/d6/7d/216a1588b65a7aa5f4535570418a599d943c85afb1d95b0876fc00aa1468/pandas-3.0.1-cp313-cp313-win_amd64.whl name: pandas - version: 2.3.3 - sha256: bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8 + version: 3.0.1 + sha256: 9fea306c783e28884c29057a1d9baa11a349bbf99538ec1da44c8476563d1b25 requires_dist: - - numpy>=1.22.4 ; python_full_version < '3.11' - - numpy>=1.23.2 ; python_full_version == '3.11.*' - - numpy>=1.26.0 ; python_full_version >= '3.12' + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' - python-dateutil>=2.8.2 - - pytz>=2020.1 - - tzdata>=2022.7 - - hypothesis>=6.46.1 ; extra == 'test' - - pytest>=7.3.2 ; extra == 'test' - - pytest-xdist>=2.2.0 ; extra == 'test' - - pyarrow>=10.0.1 ; extra == 'pyarrow' - - bottleneck>=1.3.6 ; extra == 'performance' - - numba>=0.56.4 ; extra == 'performance' - - numexpr>=2.8.4 ; extra == 'performance' - - scipy>=1.10.0 ; extra == 'computation' - - xarray>=2022.12.0 ; extra == 'computation' - - fsspec>=2022.11.0 ; extra == 'fss' - - s3fs>=2022.11.0 ; extra == 'aws' - - gcsfs>=2022.11.0 ; extra == 'gcp' - - pandas-gbq>=0.19.0 ; extra == 'gcp' + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.0 ; extra == 'excel' - - python-calamine>=0.1.7 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' - pyxlsb>=1.0.10 ; extra == 'excel' - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.0.5 ; extra == 'excel' - - pyarrow>=10.0.1 ; extra == 'parquet' - - pyarrow>=10.0.1 ; extra == 'feather' - - tables>=3.8.0 ; extra == 'hdf5' - - pyreadstat>=1.2.0 ; extra == 'spss' - - sqlalchemy>=2.0.0 ; extra == 'postgresql' - - psycopg2>=2.9.6 ; extra == 'postgresql' - - adbc-driver-postgresql>=0.8.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.0 ; extra == 'mysql' - - pymysql>=1.0.2 ; extra == 'mysql' - - sqlalchemy>=2.0.0 ; extra == 'sql-other' - - adbc-driver-postgresql>=0.8.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=0.8.0 ; extra == 'sql-other' - - beautifulsoup4>=4.11.2 ; extra == 'html' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' - html5lib>=1.1 ; extra == 'html' - - lxml>=4.9.2 ; extra == 'html' - - lxml>=4.9.2 ; extra == 'xml' - - matplotlib>=3.6.3 ; extra == 'plot' - - jinja2>=3.1.2 ; extra == 'output-formatting' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' - tabulate>=0.9.0 ; extra == 'output-formatting' - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.3.0 ; extra == 'clipboard' - - zstandard>=0.19.0 ; extra == 'compression' - - dataframe-api-compat>=0.1.7 ; extra == 'consortium-standard' - - adbc-driver-postgresql>=0.8.0 ; extra == 'all' - - adbc-driver-sqlite>=0.8.0 ; extra == 'all' - - beautifulsoup4>=4.11.2 ; extra == 'all' - - bottleneck>=1.3.6 ; extra == 'all' - - dataframe-api-compat>=0.1.7 ; extra == 'all' - - fastparquet>=2022.12.0 ; extra == 'all' - - fsspec>=2022.11.0 ; extra == 'all' - - gcsfs>=2022.11.0 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.46.1 ; extra == 'all' - - jinja2>=3.1.2 ; extra == 'all' - - lxml>=4.9.2 ; extra == 'all' - - matplotlib>=3.6.3 ; extra == 'all' - - numba>=0.56.4 ; extra == 'all' - - numexpr>=2.8.4 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.0 ; extra == 'all' - - pandas-gbq>=0.19.0 ; extra == 'all' - - psycopg2>=2.9.6 ; extra == 'all' - - pyarrow>=10.0.1 ; extra == 'all' - - pymysql>=1.0.2 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.0 ; extra == 'all' - - pytest>=7.3.2 ; extra == 'all' - - pytest-xdist>=2.2.0 ; extra == 'all' - - python-calamine>=0.1.7 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.3.0 ; extra == 'all' - - scipy>=1.10.0 ; extra == 'all' - - s3fs>=2022.11.0 ; extra == 'all' - - sqlalchemy>=2.0.0 ; extra == 'all' - - tables>=3.8.0 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2022.12.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.0.5 ; extra == 'all' - - zstandard>=0.19.0 ; extra == 'all' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/f2/85/ab6d04733a7d6ff32bfc8382bf1b07078228f5d6ebec5266b91bfc5c4ff7/pandas-3.0.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl name: pandas - version: 2.3.3 - sha256: f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee + version: 3.0.1 + sha256: 1ff8cf1d2896e34343197685f432450ec99a85ba8d90cce2030c5eee2ef98791 requires_dist: - - numpy>=1.22.4 ; python_full_version < '3.11' - - numpy>=1.23.2 ; python_full_version == '3.11.*' - - numpy>=1.26.0 ; python_full_version >= '3.12' + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' - python-dateutil>=2.8.2 - - pytz>=2020.1 - - tzdata>=2022.7 - - hypothesis>=6.46.1 ; extra == 'test' - - pytest>=7.3.2 ; extra == 'test' - - pytest-xdist>=2.2.0 ; extra == 'test' - - pyarrow>=10.0.1 ; extra == 'pyarrow' - - bottleneck>=1.3.6 ; extra == 'performance' - - numba>=0.56.4 ; extra == 'performance' - - numexpr>=2.8.4 ; extra == 'performance' - - scipy>=1.10.0 ; extra == 'computation' - - xarray>=2022.12.0 ; extra == 'computation' - - fsspec>=2022.11.0 ; extra == 'fss' - - s3fs>=2022.11.0 ; extra == 'aws' - - gcsfs>=2022.11.0 ; extra == 'gcp' - - pandas-gbq>=0.19.0 ; extra == 'gcp' + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.0 ; extra == 'excel' - - python-calamine>=0.1.7 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' - pyxlsb>=1.0.10 ; extra == 'excel' - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.0.5 ; extra == 'excel' - - pyarrow>=10.0.1 ; extra == 'parquet' - - pyarrow>=10.0.1 ; extra == 'feather' - - tables>=3.8.0 ; extra == 'hdf5' - - pyreadstat>=1.2.0 ; extra == 'spss' - - sqlalchemy>=2.0.0 ; extra == 'postgresql' - - psycopg2>=2.9.6 ; extra == 'postgresql' - - adbc-driver-postgresql>=0.8.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.0 ; extra == 'mysql' - - pymysql>=1.0.2 ; extra == 'mysql' - - sqlalchemy>=2.0.0 ; extra == 'sql-other' - - adbc-driver-postgresql>=0.8.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=0.8.0 ; extra == 'sql-other' - - beautifulsoup4>=4.11.2 ; extra == 'html' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' - html5lib>=1.1 ; extra == 'html' - - lxml>=4.9.2 ; extra == 'html' - - lxml>=4.9.2 ; extra == 'xml' - - matplotlib>=3.6.3 ; extra == 'plot' - - jinja2>=3.1.2 ; extra == 'output-formatting' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' - tabulate>=0.9.0 ; extra == 'output-formatting' - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.3.0 ; extra == 'clipboard' - - zstandard>=0.19.0 ; extra == 'compression' - - dataframe-api-compat>=0.1.7 ; extra == 'consortium-standard' - - adbc-driver-postgresql>=0.8.0 ; extra == 'all' - - adbc-driver-sqlite>=0.8.0 ; extra == 'all' - - beautifulsoup4>=4.11.2 ; extra == 'all' - - bottleneck>=1.3.6 ; extra == 'all' - - dataframe-api-compat>=0.1.7 ; extra == 'all' - - fastparquet>=2022.12.0 ; extra == 'all' - - fsspec>=2022.11.0 ; extra == 'all' - - gcsfs>=2022.11.0 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.46.1 ; extra == 'all' - - jinja2>=3.1.2 ; extra == 'all' - - lxml>=4.9.2 ; extra == 'all' - - matplotlib>=3.6.3 ; extra == 'all' - - numba>=0.56.4 ; extra == 'all' - - numexpr>=2.8.4 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.0 ; extra == 'all' - - pandas-gbq>=0.19.0 ; extra == 'all' - - psycopg2>=2.9.6 ; extra == 'all' - - pyarrow>=10.0.1 ; extra == 'all' - - pymysql>=1.0.2 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.0 ; extra == 'all' - - pytest>=7.3.2 ; extra == 'all' - - pytest-xdist>=2.2.0 ; extra == 'all' - - python-calamine>=0.1.7 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.3.0 ; extra == 'all' - - scipy>=1.10.0 ; extra == 'all' - - s3fs>=2022.11.0 ; extra == 'all' - - sqlalchemy>=2.0.0 ; extra == 'all' - - tables>=3.8.0 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2022.12.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.0.5 ; extra == 'all' - - zstandard>=0.19.0 ; extra == 'all' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/ff/07/c7087e003ceee9b9a82539b40414ec557aa795b584a1a346e89180853d79/pandas-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl name: pandas - version: 2.3.3 - sha256: 56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713 + version: 3.0.1 + sha256: de09668c1bf3b925c07e5762291602f0d789eca1b3a781f99c1c78f6cac0e7ea requires_dist: - - numpy>=1.22.4 ; python_full_version < '3.11' - - numpy>=1.23.2 ; python_full_version == '3.11.*' - - numpy>=1.26.0 ; python_full_version >= '3.12' + - numpy>=1.26.0 ; python_full_version < '3.14' + - numpy>=2.3.3 ; python_full_version >= '3.14' - python-dateutil>=2.8.2 - - pytz>=2020.1 - - tzdata>=2022.7 - - hypothesis>=6.46.1 ; extra == 'test' - - pytest>=7.3.2 ; extra == 'test' - - pytest-xdist>=2.2.0 ; extra == 'test' - - pyarrow>=10.0.1 ; extra == 'pyarrow' - - bottleneck>=1.3.6 ; extra == 'performance' - - numba>=0.56.4 ; extra == 'performance' - - numexpr>=2.8.4 ; extra == 'performance' - - scipy>=1.10.0 ; extra == 'computation' - - xarray>=2022.12.0 ; extra == 'computation' - - fsspec>=2022.11.0 ; extra == 'fss' - - s3fs>=2022.11.0 ; extra == 'aws' - - gcsfs>=2022.11.0 ; extra == 'gcp' - - pandas-gbq>=0.19.0 ; extra == 'gcp' + - tzdata ; sys_platform == 'win32' + - tzdata ; sys_platform == 'emscripten' + - hypothesis>=6.116.0 ; extra == 'test' + - pytest>=8.3.4 ; extra == 'test' + - pytest-xdist>=3.6.1 ; extra == 'test' + - pyarrow>=13.0.0 ; extra == 'pyarrow' + - bottleneck>=1.4.2 ; extra == 'performance' + - numba>=0.60.0 ; extra == 'performance' + - numexpr>=2.10.2 ; extra == 'performance' + - scipy>=1.14.1 ; extra == 'computation' + - xarray>=2024.10.0 ; extra == 'computation' + - fsspec>=2024.10.0 ; extra == 'fss' + - s3fs>=2024.10.0 ; extra == 'aws' + - gcsfs>=2024.10.0 ; extra == 'gcp' - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.0 ; extra == 'excel' - - python-calamine>=0.1.7 ; extra == 'excel' + - openpyxl>=3.1.5 ; extra == 'excel' + - python-calamine>=0.3.0 ; extra == 'excel' - pyxlsb>=1.0.10 ; extra == 'excel' - xlrd>=2.0.1 ; extra == 'excel' - - xlsxwriter>=3.0.5 ; extra == 'excel' - - pyarrow>=10.0.1 ; extra == 'parquet' - - pyarrow>=10.0.1 ; extra == 'feather' - - tables>=3.8.0 ; extra == 'hdf5' - - pyreadstat>=1.2.0 ; extra == 'spss' - - sqlalchemy>=2.0.0 ; extra == 'postgresql' - - psycopg2>=2.9.6 ; extra == 'postgresql' - - adbc-driver-postgresql>=0.8.0 ; extra == 'postgresql' - - sqlalchemy>=2.0.0 ; extra == 'mysql' - - pymysql>=1.0.2 ; extra == 'mysql' - - sqlalchemy>=2.0.0 ; extra == 'sql-other' - - adbc-driver-postgresql>=0.8.0 ; extra == 'sql-other' - - adbc-driver-sqlite>=0.8.0 ; extra == 'sql-other' - - beautifulsoup4>=4.11.2 ; extra == 'html' + - xlsxwriter>=3.2.0 ; extra == 'excel' + - pyarrow>=13.0.0 ; extra == 'parquet' + - pyarrow>=13.0.0 ; extra == 'feather' + - pyiceberg>=0.8.1 ; extra == 'iceberg' + - tables>=3.10.1 ; extra == 'hdf5' + - pyreadstat>=1.2.8 ; extra == 'spss' + - sqlalchemy>=2.0.36 ; extra == 'postgresql' + - psycopg2>=2.9.10 ; extra == 'postgresql' + - adbc-driver-postgresql>=1.2.0 ; extra == 'postgresql' + - sqlalchemy>=2.0.36 ; extra == 'mysql' + - pymysql>=1.1.1 ; extra == 'mysql' + - sqlalchemy>=2.0.36 ; extra == 'sql-other' + - adbc-driver-postgresql>=1.2.0 ; extra == 'sql-other' + - adbc-driver-sqlite>=1.2.0 ; extra == 'sql-other' + - beautifulsoup4>=4.12.3 ; extra == 'html' - html5lib>=1.1 ; extra == 'html' - - lxml>=4.9.2 ; extra == 'html' - - lxml>=4.9.2 ; extra == 'xml' - - matplotlib>=3.6.3 ; extra == 'plot' - - jinja2>=3.1.2 ; extra == 'output-formatting' + - lxml>=5.3.0 ; extra == 'html' + - lxml>=5.3.0 ; extra == 'xml' + - matplotlib>=3.9.3 ; extra == 'plot' + - jinja2>=3.1.5 ; extra == 'output-formatting' - tabulate>=0.9.0 ; extra == 'output-formatting' - pyqt5>=5.15.9 ; extra == 'clipboard' - - qtpy>=2.3.0 ; extra == 'clipboard' - - zstandard>=0.19.0 ; extra == 'compression' - - dataframe-api-compat>=0.1.7 ; extra == 'consortium-standard' - - adbc-driver-postgresql>=0.8.0 ; extra == 'all' - - adbc-driver-sqlite>=0.8.0 ; extra == 'all' - - beautifulsoup4>=4.11.2 ; extra == 'all' - - bottleneck>=1.3.6 ; extra == 'all' - - dataframe-api-compat>=0.1.7 ; extra == 'all' - - fastparquet>=2022.12.0 ; extra == 'all' - - fsspec>=2022.11.0 ; extra == 'all' - - gcsfs>=2022.11.0 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'clipboard' + - zstandard>=0.23.0 ; extra == 'compression' + - pytz>=2024.2 ; extra == 'timezone' + - adbc-driver-postgresql>=1.2.0 ; extra == 'all' + - adbc-driver-sqlite>=1.2.0 ; extra == 'all' + - beautifulsoup4>=4.12.3 ; extra == 'all' + - bottleneck>=1.4.2 ; extra == 'all' + - fastparquet>=2024.11.0 ; extra == 'all' + - fsspec>=2024.10.0 ; extra == 'all' + - gcsfs>=2024.10.0 ; extra == 'all' - html5lib>=1.1 ; extra == 'all' - - hypothesis>=6.46.1 ; extra == 'all' - - jinja2>=3.1.2 ; extra == 'all' - - lxml>=4.9.2 ; extra == 'all' - - matplotlib>=3.6.3 ; extra == 'all' - - numba>=0.56.4 ; extra == 'all' - - numexpr>=2.8.4 ; extra == 'all' + - hypothesis>=6.116.0 ; extra == 'all' + - jinja2>=3.1.5 ; extra == 'all' + - lxml>=5.3.0 ; extra == 'all' + - matplotlib>=3.9.3 ; extra == 'all' + - numba>=0.60.0 ; extra == 'all' + - numexpr>=2.10.2 ; extra == 'all' - odfpy>=1.4.1 ; extra == 'all' - - openpyxl>=3.1.0 ; extra == 'all' - - pandas-gbq>=0.19.0 ; extra == 'all' - - psycopg2>=2.9.6 ; extra == 'all' - - pyarrow>=10.0.1 ; extra == 'all' - - pymysql>=1.0.2 ; extra == 'all' + - openpyxl>=3.1.5 ; extra == 'all' + - psycopg2>=2.9.10 ; extra == 'all' + - pyarrow>=13.0.0 ; extra == 'all' + - pyiceberg>=0.8.1 ; extra == 'all' + - pymysql>=1.1.1 ; extra == 'all' - pyqt5>=5.15.9 ; extra == 'all' - - pyreadstat>=1.2.0 ; extra == 'all' - - pytest>=7.3.2 ; extra == 'all' - - pytest-xdist>=2.2.0 ; extra == 'all' - - python-calamine>=0.1.7 ; extra == 'all' + - pyreadstat>=1.2.8 ; extra == 'all' + - pytest>=8.3.4 ; extra == 'all' + - pytest-xdist>=3.6.1 ; extra == 'all' + - python-calamine>=0.3.0 ; extra == 'all' + - pytz>=2024.2 ; extra == 'all' - pyxlsb>=1.0.10 ; extra == 'all' - - qtpy>=2.3.0 ; extra == 'all' - - scipy>=1.10.0 ; extra == 'all' - - s3fs>=2022.11.0 ; extra == 'all' - - sqlalchemy>=2.0.0 ; extra == 'all' - - tables>=3.8.0 ; extra == 'all' + - qtpy>=2.4.2 ; extra == 'all' + - scipy>=1.14.1 ; extra == 'all' + - s3fs>=2024.10.0 ; extra == 'all' + - sqlalchemy>=2.0.36 ; extra == 'all' + - tables>=3.10.1 ; extra == 'all' - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2022.12.0 ; extra == 'all' + - xarray>=2024.10.0 ; extra == 'all' - xlrd>=2.0.1 ; extra == 'all' - - xlsxwriter>=3.0.5 ; extra == 'all' - - zstandard>=0.19.0 ; extra == 'all' - requires_python: '>=3.9' + - xlsxwriter>=3.2.0 ; extra == 'all' + - zstandard>=0.23.0 ; extra == 'all' + requires_python: '>=3.11' - pypi: https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl name: pandocfilters version: 1.5.1 sha256: 93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' -- pypi: https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl name: parso - version: 0.8.5 - sha256: 646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887 + version: 0.8.6 + sha256: 2c549f800b70a5c4952197248825584cb00f033b29c692671d3bf08bf380baff requires_dist: - pytest ; extra == 'testing' - docopt ; extra == 'testing' - flake8==5.0.4 ; extra == 'qa' - - mypy==0.971 ; extra == 'qa' + - zuban==0.5.1 ; extra == 'qa' - types-setuptools==67.2.0.1 ; extra == 'qa' requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl name: pathspec - version: 0.12.1 - sha256: a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08 - requires_python: '>=3.8' + version: 1.0.4 + sha256: fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 + requires_dist: + - hyperscan>=0.7 ; extra == 'hyperscan' + - typing-extensions>=4 ; extra == 'optional' + - google-re2>=1.1 ; extra == 're2' + - pytest>=9 ; extra == 'tests' + - typing-extensions>=4.15 ; extra == 'tests' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl name: pexpect version: 4.9.0 sha256: 7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523 requires_dist: - ptyprocess>=0.5 -- pypi: https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/14/a1/16c4b823838ba4c9c52c0e6bbda903a3fe5a1bdbf1b8eb4fff7156f3e318/pillow-12.1.1-cp313-cp313-macosx_10_13_x86_64.whl + name: pillow + version: 12.1.1 + sha256: 6c6db3b84c87d48d0088943bf33440e0c42370b99b1c2a7989216f7b42eede60 + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/2b/46/5da1ec4a5171ee7bf1a0efa064aba70ba3d6e0788ce3f5acd1375d23c8c0/pillow-12.1.1-cp311-cp311-macosx_10_10_x86_64.whl + name: pillow + version: 12.1.1 + sha256: e879bb6cd5c73848ef3b2b48b8af9ff08c5b71ecda8048b7dd22d8a33f60be32 + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/31/03/bef822e4f2d8f9d7448c133d0a18185d3cce3e70472774fffefe8b0ed562/pillow-12.1.1-cp311-cp311-win_amd64.whl + name: pillow + version: 12.1.1 + sha256: fbfa2a7c10cc2623f412753cddf391c7f971c52ca40a3f65dc5039b2939e8563 + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/3f/eb/b0834ad8b583d7d9d42b80becff092082a1c3c156bb582590fcc973f1c7c/pillow-12.1.1-cp313-cp313-win_amd64.whl + name: pillow + version: 12.1.1 + sha256: 344cf1e3dab3be4b1fa08e449323d98a2a3f819ad20f4b22e77a0ede31f0faa1 + requires_dist: + - furo ; extra == 'docs' + - olefile ; extra == 'docs' + - sphinx>=8.2 ; extra == 'docs' + - sphinx-autobuild ; extra == 'docs' + - sphinx-copybutton ; extra == 'docs' + - sphinx-inline-tabs ; extra == 'docs' + - sphinxext-opengraph ; extra == 'docs' + - olefile ; extra == 'fpx' + - olefile ; extra == 'mic' + - arro3-compute ; extra == 'test-arrow' + - arro3-core ; extra == 'test-arrow' + - nanoarrow ; extra == 'test-arrow' + - pyarrow ; extra == 'test-arrow' + - check-manifest ; extra == 'tests' + - coverage>=7.4.2 ; extra == 'tests' + - defusedxml ; extra == 'tests' + - markdown2 ; extra == 'tests' + - olefile ; extra == 'tests' + - packaging ; extra == 'tests' + - pyroma>=5 ; extra == 'tests' + - pytest ; extra == 'tests' + - pytest-cov ; extra == 'tests' + - pytest-timeout ; extra == 'tests' + - pytest-xdist ; extra == 'tests' + - trove-classifiers>=2024.10.12 ; extra == 'tests' + - defusedxml ; extra == 'xmp' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/71/24/538bff45bde96535d7d998c6fed1a751c75ac7c53c37c90dc2601b243893/pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl name: pillow - version: 12.0.0 - sha256: f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344 + version: 12.1.1 + sha256: 47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717 requires_dist: - furo ; extra == 'docs' - olefile ; extra == 'docs' @@ -3883,10 +7913,10 @@ packages: - trove-classifiers>=2024.10.12 ; extra == 'tests' - defusedxml ; extra == 'xmp' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/78/93/a29e9bc02d1cf557a834da780ceccd54e02421627200696fcf805ebdc3fb/pillow-12.1.1-cp311-cp311-macosx_11_0_arm64.whl name: pillow - version: 12.0.0 - sha256: 4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905 + version: 12.1.1 + sha256: 365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38 requires_dist: - furo ; extra == 'docs' - olefile ; extra == 'docs' @@ -3915,10 +7945,10 @@ packages: - trove-classifiers>=2024.10.12 ; extra == 'tests' - defusedxml ; extra == 'xmp' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/a2/c8/46dfeac5825e600579157eea177be43e2f7ff4a99da9d0d0a49533509ac5/pillow-12.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl name: pillow - version: 12.0.0 - sha256: 5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b + version: 12.1.1 + sha256: 597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b requires_dist: - furo ; extra == 'docs' - olefile ; extra == 'docs' @@ -3947,10 +7977,10 @@ packages: - trove-classifiers>=2024.10.12 ; extra == 'tests' - defusedxml ; extra == 'xmp' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/bb/ad/ad9dc98ff24f485008aa5cdedaf1a219876f6f6c42a4626c08bc4e80b120/pillow-12.1.1-cp313-cp313-macosx_11_0_arm64.whl name: pillow - version: 12.0.0 - sha256: c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5 + version: 12.1.1 + sha256: 8b7e5304e34942bf62e15184219a7b5ad4ff7f3bb5cca4d984f37df1a0e1aee2 requires_dist: - furo ; extra == 'docs' - olefile ; extra == 'docs' @@ -3979,26 +8009,27 @@ packages: - trove-classifiers>=2024.10.12 ; extra == 'tests' - defusedxml ; extra == 'xmp' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/c4/36/ce5f75aa7c736a663a901766edc3580098c7ea3959a0e878363a54a3714e/pixi_kernel-0.7.1-py3-none-any.whl + name: pixi-kernel + version: 0.7.1 + sha256: 93b51c8a95ca58fb4b743cb2ce5d73b951f467e7c39b0c766f20e05bdf950478 + requires_dist: + - ipykernel>=6 + - jupyter-client>=7 + - jupyter-server>=2.4 + - msgspec>=0.18 + - returns>=0.23 + - tomli>=2 ; python_full_version < '3.11' + requires_python: '>=3.10,<4.0' +- pypi: https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl name: platformdirs - version: 4.5.0 - sha256: e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3 - requires_dist: - - furo>=2025.9.25 ; extra == 'docs' - - proselint>=0.14 ; extra == 'docs' - - sphinx-autodoc-typehints>=3.2 ; extra == 'docs' - - sphinx>=8.2.3 ; extra == 'docs' - - appdirs==1.4.4 ; extra == 'test' - - covdefaults>=2.3 ; extra == 'test' - - pytest-cov>=7 ; extra == 'test' - - pytest-mock>=3.15.1 ; extra == 'test' - - pytest>=8.4.2 ; extra == 'test' - - mypy>=1.18.2 ; extra == 'type' + version: 4.9.2 + sha256: 9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/e7/c3/3031c931098de393393e1f93a38dc9ed6805d86bb801acc3cf2d5bd1e6b7/plotly-6.5.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl name: plotly - version: 6.5.0 - sha256: 5ac851e100367735250206788a2b1325412aa4a4917a4fe3e6f0bc5aa6f3d90a + version: 6.6.0 + sha256: 8d6daf0f87412e0c0bfe72e809d615217ab57cc715899a1e5145135a7800d1d0 requires_dist: - narwhals>=1.15.1 - packaging @@ -4046,12 +8077,47 @@ packages: - pytest-benchmark ; extra == 'testing' - coverage ; extra == 'testing' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/79/ad/45312df6b63ba64ea35b8d8f5f0c577aac16e6b416eafe8e1cb34e03f9a7/plumbum-1.10.0-py3-none-any.whl + name: plumbum + version: 1.10.0 + sha256: 9583d737ac901c474d99d030e4d5eec4c4e6d2d7417b1cf49728cf3be34f6dc8 + requires_dist: + - pywin32 ; platform_python_implementation != 'PyPy' and sys_platform == 'win32' + - paramiko ; extra == 'ssh' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl + name: pooch + version: 1.9.0 + sha256: f265597baa9f760d25ceb29d0beb8186c243d6607b0f60b83ecf14078dbc703b + requires_dist: + - platformdirs>=2.5.0 + - packaging>=20.0 + - requests>=2.19.0 + - tqdm>=4.41.0,<5.0.0 ; extra == 'progress' + - paramiko>=2.7.0 ; extra == 'sftp' + - xxhash>=1.4.3 ; extra == 'xxhash' + - pytest-httpserver ; extra == 'test' + - pytest-localftpserver ; extra == 'test' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl + name: pre-commit + version: 4.5.1 + sha256: 3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77 + requires_dist: + - cfgv>=2.0.0 + - identify>=1.0.0 + - nodeenv>=0.11.1 + - pyyaml>=5.1 + - virtualenv>=20.10.0 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/74/c3/24a2f845e3917201628ecaba4f18bab4d18a337834c1df2a159ee9d22a42/prometheus_client-0.24.1-py3-none-any.whl name: prometheus-client - version: 0.23.1 - sha256: dd1913e6e76b59cfe44e7a4b83e01afc9873c1bdfd2ed8739f1e76aeca115f99 + version: 0.24.1 + sha256: 150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 requires_dist: - twisted ; extra == 'twisted' + - aiohttp ; extra == 'aiohttp' + - django ; extra == 'django' requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl name: prompt-toolkit @@ -4060,6 +8126,11 @@ packages: requires_dist: - wcwidth requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: propcache + version: 0.4.1 + sha256: fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl name: propcache version: 0.4.1 @@ -4070,24 +8141,39 @@ packages: version: 0.4.1 sha256: d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/c2/21/d7b68e911f9c8e18e4ae43bdbc1e1e9bbd971f8866eb81608947b6f585ff/propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl + name: propcache + version: 0.4.1 + sha256: c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl + name: propcache + version: 0.4.1 + sha256: 6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: propcache version: 0.4.1 sha256: d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl + name: propcache + version: 0.4.1 + sha256: 364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl name: propcache version: 0.4.1 sha256: 381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/55/4c/c3ed1a622b6ae2fd3c945a366e64eb35247a31e4db16cf5095e269e8eb3c/psutil-7.1.3-cp37-abi3-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl name: psutil - version: 7.1.3 - sha256: f39c2c19fe824b47484b96f9692932248a54c43799a84282cfe58d05a6449efd + version: 7.2.2 + sha256: 1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979 requires_dist: + - psleak ; extra == 'dev' - pytest ; extra == 'dev' - pytest-instafail ; extra == 'dev' - - pytest-subtests ; extra == 'dev' - pytest-xdist ; extra == 'dev' - setuptools ; extra == 'dev' - abi3audit ; extra == 'dev' @@ -4111,27 +8197,27 @@ packages: - vulture ; extra == 'dev' - wheel ; extra == 'dev' - colorama ; os_name == 'nt' and extra == 'dev' - - pyreadline ; os_name == 'nt' and extra == 'dev' - - pywin32 ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'dev' - - wheel ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'dev' - - wmi ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'dev' + - pyreadline3 ; os_name == 'nt' and extra == 'dev' + - pywin32 ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'dev' + - wheel ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'dev' + - wmi ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'dev' + - psleak ; extra == 'test' - pytest ; extra == 'test' - pytest-instafail ; extra == 'test' - - pytest-subtests ; extra == 'test' - pytest-xdist ; extra == 'test' - setuptools ; extra == 'test' - - pywin32 ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'test' - - wheel ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'test' - - wmi ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'test' + - pywin32 ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' + - wheel ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' + - wmi ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/68/3a/9f93cff5c025029a36d9a92fef47220ab4692ee7f2be0fba9f92813d0cb8/psutil-7.1.3-cp36-abi3-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl name: psutil - version: 7.1.3 - sha256: bc31fa00f1fbc3c3802141eede66f3a2d51d89716a194bf2cd6fc68310a19880 + version: 7.2.2 + sha256: eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988 requires_dist: + - psleak ; extra == 'dev' - pytest ; extra == 'dev' - pytest-instafail ; extra == 'dev' - - pytest-subtests ; extra == 'dev' - pytest-xdist ; extra == 'dev' - setuptools ; extra == 'dev' - abi3audit ; extra == 'dev' @@ -4155,27 +8241,27 @@ packages: - vulture ; extra == 'dev' - wheel ; extra == 'dev' - colorama ; os_name == 'nt' and extra == 'dev' - - pyreadline ; os_name == 'nt' and extra == 'dev' - - pywin32 ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'dev' - - wheel ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'dev' - - wmi ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'dev' + - pyreadline3 ; os_name == 'nt' and extra == 'dev' + - pywin32 ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'dev' + - wheel ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'dev' + - wmi ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'dev' + - psleak ; extra == 'test' - pytest ; extra == 'test' - pytest-instafail ; extra == 'test' - - pytest-subtests ; extra == 'test' - pytest-xdist ; extra == 'test' - setuptools ; extra == 'test' - - pywin32 ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'test' - - wheel ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'test' - - wmi ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'test' + - pywin32 ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' + - wheel ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' + - wmi ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/ce/b1/5f49af514f76431ba4eea935b8ad3725cdeb397e9245ab919dbc1d1dc20f/psutil-7.1.3-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl name: psutil - version: 7.1.3 - sha256: 3bb428f9f05c1225a558f53e30ccbad9930b11c3fc206836242de1091d3e7dd3 + version: 7.2.2 + sha256: 076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9 requires_dist: + - psleak ; extra == 'dev' - pytest ; extra == 'dev' - pytest-instafail ; extra == 'dev' - - pytest-subtests ; extra == 'dev' - pytest-xdist ; extra == 'dev' - setuptools ; extra == 'dev' - abi3audit ; extra == 'dev' @@ -4199,27 +8285,27 @@ packages: - vulture ; extra == 'dev' - wheel ; extra == 'dev' - colorama ; os_name == 'nt' and extra == 'dev' - - pyreadline ; os_name == 'nt' and extra == 'dev' - - pywin32 ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'dev' - - wheel ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'dev' - - wmi ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'dev' + - pyreadline3 ; os_name == 'nt' and extra == 'dev' + - pywin32 ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'dev' + - wheel ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'dev' + - wmi ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'dev' + - psleak ; extra == 'test' - pytest ; extra == 'test' - pytest-instafail ; extra == 'test' - - pytest-subtests ; extra == 'test' - pytest-xdist ; extra == 'test' - setuptools ; extra == 'test' - - pywin32 ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'test' - - wheel ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'test' - - wmi ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'test' + - pywin32 ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' + - wheel ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' + - wmi ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/ef/94/46b9154a800253e7ecff5aaacdf8ebf43db99de4a2dfa18575b02548654e/psutil-7.1.3-cp36-abi3-macosx_10_9_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl name: psutil - version: 7.1.3 - sha256: 2bdbcd0e58ca14996a42adf3621a6244f1bb2e2e528886959c72cf1e326677ab + version: 7.2.2 + sha256: ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 requires_dist: + - psleak ; extra == 'dev' - pytest ; extra == 'dev' - pytest-instafail ; extra == 'dev' - - pytest-subtests ; extra == 'dev' - pytest-xdist ; extra == 'dev' - setuptools ; extra == 'dev' - abi3audit ; extra == 'dev' @@ -4243,18 +8329,18 @@ packages: - vulture ; extra == 'dev' - wheel ; extra == 'dev' - colorama ; os_name == 'nt' and extra == 'dev' - - pyreadline ; os_name == 'nt' and extra == 'dev' - - pywin32 ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'dev' - - wheel ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'dev' - - wmi ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'dev' + - pyreadline3 ; os_name == 'nt' and extra == 'dev' + - pywin32 ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'dev' + - wheel ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'dev' + - wmi ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'dev' + - psleak ; extra == 'test' - pytest ; extra == 'test' - pytest-instafail ; extra == 'test' - - pytest-subtests ; extra == 'test' - pytest-xdist ; extra == 'test' - setuptools ; extra == 'test' - - pywin32 ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'test' - - wheel ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'test' - - wmi ; os_name == 'nt' and platform_python_implementation != 'PyPy' and extra == 'test' + - pywin32 ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' + - wheel ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' + - wmi ; implementation_name != 'pypy' and os_name == 'nt' and extra == 'test' requires_python: '>=3.6' - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl name: ptyprocess @@ -4266,73 +8352,88 @@ packages: sha256: 1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0 requires_dist: - pytest ; extra == 'tests' +- pypi: https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl + name: py + version: 1.11.0 + sha256: 607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*' - pypi: https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl name: pycodestyle version: 2.14.0 sha256: dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl name: pycparser - version: '2.23' - sha256: e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934 - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/e7/d3/c622950d87a2ffd1654208733b5bd1c5645930014abed8f4c0d74863988b/pydata_sphinx_theme-0.15.4-py3-none-any.whl - name: pydata-sphinx-theme - version: 0.15.4 - sha256: 2136ad0e9500d0949f96167e63f3e298620040aea8f9c74621959eda5d4cf8e6 + version: '3.0' + sha256: b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl + name: pydantic + version: 2.12.5 + sha256: e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d + requires_dist: + - annotated-types>=0.6.0 + - pydantic-core==2.41.5 + - typing-extensions>=4.14.1 + - typing-inspection>=0.4.2 + - email-validator>=2.0.0 ; extra == 'email' + - tzdata ; python_full_version >= '3.9' and sys_platform == 'win32' and extra == 'timezone' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/11/66/f14d1d978ea94d1bc21fc98fcf570f9542fe55bfcc40269d4e1a21c19bf7/pydantic_core-2.41.5-cp311-cp311-win_amd64.whl + name: pydantic-core + version: 2.41.5 + sha256: 76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe requires_dist: - - sphinx>=5 - - beautifulsoup4 - - docutils!=0.17.0 - - packaging - - babel - - pygments>=2.7 - - accessible-pygments - - typing-extensions - - numpydoc ; extra == 'doc' - - linkify-it-py ; extra == 'doc' - - rich ; extra == 'doc' - - sphinxext-rediraffe ; extra == 'doc' - - sphinx-sitemap ; extra == 'doc' - - sphinx-autoapi>=3.0.0 ; extra == 'doc' - - myst-parser ; extra == 'doc' - - ablog>=0.11.8 ; extra == 'doc' - - jupyter-sphinx ; extra == 'doc' - - pandas ; extra == 'doc' - - plotly ; extra == 'doc' - - matplotlib ; extra == 'doc' - - numpy ; extra == 'doc' - - xarray ; extra == 'doc' - - sphinx-copybutton ; extra == 'doc' - - sphinx-design ; extra == 'doc' - - sphinx-togglebutton ; extra == 'doc' - - jupyterlite-sphinx ; extra == 'doc' - - sphinxcontrib-youtube>=1.4.1 ; extra == 'doc' - - sphinx-favicon>=1.0.1 ; extra == 'doc' - - ipykernel ; extra == 'doc' - - nbsphinx ; extra == 'doc' - - ipyleaflet ; extra == 'doc' - - colorama ; extra == 'doc' - - ipywidgets ; extra == 'doc' - - graphviz ; extra == 'doc' - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-regressions ; extra == 'test' - - sphinx[test] ; extra == 'test' - - pyyaml ; extra == 'dev' - - pre-commit ; extra == 'dev' - - pydata-sphinx-theme[doc,test] ; extra == 'dev' - - tox ; extra == 'dev' - - pandoc ; extra == 'dev' - - sphinx-theme-builder[cli] ; extra == 'dev' - - pytest-playwright ; extra == 'a11y' - - babel ; extra == 'i18n' - - jinja2 ; extra == 'i18n' + - typing-extensions>=4.14.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/12/44/37e403fd9455708b3b942949e1d7febc02167662bf1a7da5b78ee1ea2842/pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl + name: pydantic-core + version: 2.41.5 + sha256: 7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b + requires_dist: + - typing-extensions>=4.14.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl + name: pydantic-core + version: 2.41.5 + sha256: 941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 + requires_dist: + - typing-extensions>=4.14.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl + name: pydantic-core + version: 2.41.5 + sha256: 112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 + requires_dist: + - typing-extensions>=4.14.1 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl - name: pyflakes - version: 3.4.0 - sha256: f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f +- pypi: https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl + name: pydantic-core + version: 2.41.5 + sha256: 79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 + requires_dist: + - typing-extensions>=4.14.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/c8/be/8fed28dd0a180dca19e72c233cbf58efa36df055e5b9d90d64fd1740b828/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: pydantic-core + version: 2.41.5 + sha256: f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b + requires_dist: + - typing-extensions>=4.14.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: pydantic-core + version: 2.41.5 + sha256: 406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 + requires_dist: + - typing-extensions>=4.14.1 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/e8/72/74a989dd9f2084b3d9530b0915fdda64ac48831c30dbf7c72a41a5232db8/pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl + name: pydantic-core + version: 2.41.5 + sha256: a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 + requires_dist: + - typing-extensions>=4.14.1 requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl name: pygments @@ -4341,38 +8442,32 @@ packages: requires_dist: - colorama>=0.4.6 ; extra == 'windows-terminal' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/6f/2c/5b079febdc65e1c3fb2729bf958d18b45be7113828528e8a0b5850dd819a/pymdown_extensions-10.21-py3-none-any.whl + name: pymdown-extensions + version: '10.21' + sha256: 91b879f9f864d49794c2d9534372b10150e6141096c3908a455e45ca72ad9d3f + requires_dist: + - markdown>=3.6 + - pyyaml + - pygments>=2.19.1 ; extra == 'extra' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl name: pyparsing - version: 3.2.5 - sha256: e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e + version: 3.3.2 + sha256: 850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d requires_dist: - railroad-diagrams ; extra == 'diagrams' - jinja2 ; extra == 'diagrams' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/54/cc/cecf97be298bee2b2a37dd360618c819a2a7fd95251d8e480c1f0eb88f3b/pyproject_api-1.10.0-py3-none-any.whl - name: pyproject-api - version: 1.10.0 - sha256: 8757c41a79c0f4ab71b99abed52b97ecf66bd20b04fa59da43b5840bac105a09 - requires_dist: - - packaging>=25 - - tomli>=2.3 ; python_full_version < '3.11' - - furo>=2025.9.25 ; extra == 'docs' - - sphinx-autodoc-typehints>=3.5.1 ; extra == 'docs' - - covdefaults>=2.3 ; extra == 'testing' - - pytest-cov>=7 ; extra == 'testing' - - pytest-mock>=3.15.1 ; extra == 'testing' - - pytest>=8.4.2 ; extra == 'testing' - - setuptools>=80.9 ; extra == 'testing' - requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl name: pyproject-hooks version: 1.2.0 sha256: 9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913 requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl name: pytest - version: 9.0.1 - sha256: 67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad + version: 9.0.2 + sha256: 711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b requires_dist: - colorama>=0.4 ; sys_platform == 'win32' - exceptiongroup>=1 ; python_full_version < '3.11' @@ -4401,94 +8496,202 @@ packages: - pytest-xdist ; extra == 'testing' - virtualenv ; extra == 'testing' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda - build_number: 101 - sha256: e89da062abd0d3e76c8d3b35d3cafc5f0d05914339dcb238f9e3675f2a58d883 - md5: 4780fe896e961722d0623fa91d0d3378 +- pypi: https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl + name: pytest-xdist + version: 3.8.0 + sha256: 202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 + requires_dist: + - execnet>=2.1 + - pytest>=7.0.0 + - filelock ; extra == 'testing' + - psutil>=3.0 ; extra == 'psutil' + - setproctitle ; extra == 'setproctitle' + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda + build_number: 3 + sha256: 41b29c2d62f7028bb7bb05eef3ff55f81e3c1cb40e76ba95a890a058fbc2a896 + md5: 26d8f4db8c578dedba9f2c11423e59e5 depends: - __glibc >=2.17,<3.0.a0 - bzip2 >=1.0.8,<2.0a0 - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.7.1,<3.0a0 + - libexpat >=2.7.3,<3.0a0 - libffi >=3.5.2,<3.6.0a0 - libgcc >=14 - - liblzma >=5.8.1,<6.0a0 - - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.50.4,<4.0a0 - - libuuid >=2.41.2,<3.0a0 + - liblzma >=5.8.2,<6.0a0 + - libnsl >=2.0.1,<2.1.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libuuid >=2.41.3,<3.0a0 + - libxcrypt >=4.4.36 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - openssl >=3.5.4,<4.0a0 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + constrains: + - python_abi 3.11.* *_cp311 + license: Python-2.0 + purls: [] + size: 30905206 + timestamp: 1769472446175 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda + build_number: 100 + sha256: 8a08fe5b7cb5a28aa44e2994d18dbf77f443956990753a4ca8173153ffb6eb56 + md5: 4c875ed0e78c2d407ec55eadffb8cf3d + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - ld_impl_linux-64 >=2.36.1 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libuuid >=2.41.3,<3.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 - python_abi 3.13.* *_cp313 - - readline >=8.2,<9.0a0 + - readline >=8.3,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata license: Python-2.0 purls: [] - size: 37174029 - timestamp: 1761178179147 + size: 37364553 + timestamp: 1770272309861 python_site_packages_path: lib/python3.13/site-packages -- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.9-h17c18a5_101_cp313.conda - build_number: 101 - sha256: b56484229cf83f6c84e8b138dc53f7f2fa9ee850f42bf1f6d6fa1c03c044c2d3 - md5: fb1e51574ce30d2a4d5e4facb9b2cbd5 +- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.11.14-h74c2667_3_cpython.conda + build_number: 3 + sha256: 327d6c5eb61657d4b76e1024da9c790d3e7aacee84487403e9eef1b730982e63 + md5: df79e5958af70212260d5e163e867d98 depends: - __osx >=10.13 - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.1,<3.0a0 + - libexpat >=2.7.3,<3.0a0 - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.1,<6.0a0 - - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.50.4,<4.0a0 + - liblzma >=5.8.2,<6.0a0 + - libsqlite >=3.51.2,<4.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - openssl >=3.5.4,<4.0a0 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + constrains: + - python_abi 3.11.* *_cp311 + license: Python-2.0 + purls: [] + size: 15666344 + timestamp: 1769473006716 +- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.12-h894a449_100_cp313.conda + build_number: 100 + sha256: 9548dcf58cf6045aa4aa1f2f3fa6110115ca616a8d5fa142a24081d2b9d91291 + md5: 99b1fa1fe8a8ab58224969f4568aadca + depends: + - __osx >=10.13 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 - python_abi 3.13.* *_cp313 - - readline >=8.2,<9.0a0 + - readline >=8.3,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata license: Python-2.0 purls: [] - size: 17521522 - timestamp: 1761177097697 + size: 17570178 + timestamp: 1770272361922 python_site_packages_path: lib/python3.13/site-packages -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.9-hfc2f54d_101_cp313.conda - build_number: 101 - sha256: 516229f780b98783a5ef4112a5a4b5e5647d4f0177c4621e98aa60bb9bc32f98 - md5: a4241bce59eecc74d4d2396e108c93b8 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.14-h18782d2_3_cpython.conda + build_number: 3 + sha256: f862d544a455bedfa5d77305f0a42c8e3392956e364f8f92d6ca1c844fb3fbd1 + md5: b8f6a28ffd3c97367d4e58e8793ff47c depends: - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.1,<3.0a0 + - libexpat >=2.7.3,<3.0a0 - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.1,<6.0a0 - - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.50.4,<4.0a0 + - liblzma >=5.8.2,<6.0a0 + - libsqlite >=3.51.2,<4.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - openssl >=3.5.4,<4.0a0 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + constrains: + - python_abi 3.11.* *_cp311 + license: Python-2.0 + purls: [] + size: 13707418 + timestamp: 1769472290774 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.12-h20e6be0_100_cp313.conda + build_number: 100 + sha256: 9a4f16a64def0853f0a7b6a7beb40d498fd6b09bee10b90c3d6069b664156817 + md5: 179c0f5ae4f22bc3be567298ed0b17b9 + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 - python_abi 3.13.* *_cp313 - - readline >=8.2,<9.0a0 + - readline >=8.3,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata license: Python-2.0 purls: [] - size: 11915380 - timestamp: 1761176793936 + size: 12770674 + timestamp: 1770272314517 python_site_packages_path: lib/python3.13/site-packages -- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.9-h09917c8_101_cp313.conda - build_number: 101 - sha256: bc855b513197637c2083988d5cbdcc407a23151cdecff381bd677df33d516a01 - md5: 89d992b9d4b9e88ed54346c9c4a24c1c +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.14-h0159041_3_cpython.conda + build_number: 3 + sha256: 5676dadd9d4fba1bce51bd7e5cf8fcf76f85b88b7baa15bd10ca00557e67f10e + md5: 05ded1dca7befb66ec95a9ec6d34a71a depends: - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.1,<3.0a0 + - libexpat >=2.7.3,<3.0a0 - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.1,<6.0a0 - - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.50.4,<4.0a0 + - liblzma >=5.8.2,<6.0a0 + - libsqlite >=3.51.2,<4.0a0 - libzlib >=1.3.1,<2.0a0 - openssl >=3.5.4,<4.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - python_abi 3.11.* *_cp311 + license: Python-2.0 + purls: [] + size: 18353938 + timestamp: 1769471078924 +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.12-h09917c8_100_cp313.conda + build_number: 100 + sha256: da70aec20ff5a5ae18bbba9fdd1e18190b419605cafaafb3bdad8becf11ce94d + md5: 4440c24966d0aa0c8f1e1d5006dac2d6 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 - python_abi 3.13.* *_cp313 - tk >=8.6.13,<8.7.0a0 - tzdata @@ -4497,8 +8700,8 @@ packages: - vc14_runtime >=14.44.35208 license: Python-2.0 purls: [] - size: 16613183 - timestamp: 1761175050438 + size: 16535316 + timestamp: 1770270322707 python_site_packages_path: Lib/site-packages - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl name: python-dateutil @@ -4507,17 +8710,36 @@ packages: requires_dist: - six>=1.5 requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' -- pypi: https://files.pythonhosted.org/packages/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl + name: python-discovery + version: 1.1.0 + sha256: a162893b8809727f54594a99ad2179d2ede4bf953e12d4c7abc3cc9cdbd1437b + requires_dist: + - filelock>=3.15.4 + - platformdirs>=4.3.6,<5 + - furo>=2025.12.19 ; extra == 'docs' + - sphinx-autodoc-typehints>=3.6.3 ; extra == 'docs' + - sphinx>=9.1 ; extra == 'docs' + - sphinxcontrib-mermaid>=2 ; extra == 'docs' + - covdefaults>=2.3 ; extra == 'testing' + - coverage>=7.5.4 ; extra == 'testing' + - pytest-mock>=3.14 ; extra == 'testing' + - pytest>=8.3.5 ; extra == 'testing' + - setuptools>=75.1 ; extra == 'testing' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl name: python-engineio - version: 4.12.3 - sha256: 7c099abb2a27ea7ab429c04da86ab2d82698cdd6c52406cb73766fe454feb7e1 + version: 4.13.1 + sha256: f32ad10589859c11053ad7d9bb3c9695cdf862113bfb0d20bc4d890198287399 requires_dist: - simple-websocket>=0.10.0 - requests>=2.21.0 ; extra == 'client' - websocket-client>=0.54.0 ; extra == 'client' - - aiohttp>=3.4 ; extra == 'asyncio-client' + - aiohttp>=3.11 ; extra == 'asyncio-client' + - tox ; extra == 'dev' - sphinx ; extra == 'docs' - requires_python: '>=3.6' + - furo ; extra == 'docs' + requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl name: python-json-logger version: 4.0.0 @@ -4544,10 +8766,10 @@ packages: - mkdocs-literate-nav ; extra == 'dev' - mike ; extra == 'dev' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/cd/fa/1ef2f8537272a2f383d72b9301c3ef66a49710b3bb7dcb2bd138cf2920d1/python_socketio-5.15.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl name: python-socketio - version: 5.15.0 - sha256: e93363102f4da6d8e7a8872bf4908b866c40f070e716aa27132891e643e2687c + version: 5.16.1 + sha256: a3eb1702e92aa2f2b5d3ba00261b61f062cce51f1cfb6900bf3ab4d1934d2d35 requires_dist: - bidict>=0.21.0 - python-engineio>=4.11.0 @@ -4556,6 +8778,7 @@ packages: - aiohttp>=3.4 ; extra == 'asyncio-client' - tox ; extra == 'dev' - sphinx ; extra == 'docs' + - furo ; extra == 'docs' requires_python: '>=3.8' - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda build_number: 8 @@ -4568,15 +8791,39 @@ packages: purls: [] size: 7002 timestamp: 1752805902938 -- pypi: https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl - name: pytz - version: '2025.2' - sha256: 5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 -- pypi: https://files.pythonhosted.org/packages/fc/19/b757fe28008236a4a713e813283721b8a40aa60cd7d3f83549f2e25a3155/pywinpty-3.0.2-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/51/8f/9bb81dd5bb77d22243d33c8397f09377056d5c687aa6d4042bea7fbf8364/pywin32-311-cp311-cp311-win_amd64.whl + name: pywin32 + version: '311' + sha256: 3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503 +- pypi: https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl + name: pywin32 + version: '311' + sha256: 718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d +- pypi: https://files.pythonhosted.org/packages/79/c3/3e75075c7f71735f22b66fab0481f2c98e3a4d58cba55cb50ba29114bcf6/pywinpty-3.0.3-cp311-cp311-win_amd64.whl + name: pywinpty + version: 3.0.3 + sha256: dff25a9a6435f527d7c65608a7e62783fc12076e7d44487a4911ee91be5a8ac8 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/e5/cb/58d6ed3fd429c96a90ef01ac9a617af10a6d41469219c25e7dc162abbb71/pywinpty-3.0.3-cp313-cp313-win_amd64.whl name: pywinpty - version: 3.0.2 - sha256: 18f78b81e4cfee6aabe7ea8688441d30247b73e52cd9657138015c5f4ee13a51 + version: 3.0.3 + sha256: 9c91dbb026050c77bdcef964e63a4f10f01a639113c4d3658332614544c467ab requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl + name: pyyaml + version: 6.0.3 + sha256: 652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl + name: pyyaml + version: 6.0.3 + sha256: 44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: pyyaml + version: 6.0.3 + sha256: b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d + requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: pyyaml version: 6.0.3 @@ -4597,6 +8844,32 @@ packages: version: 6.0.3 sha256: 8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8 requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl + name: pyyaml + version: 6.0.3 + sha256: 9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl + name: pyyaml-env-tag + version: '1.1' + sha256: 17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04 + requires_dist: + - pyyaml + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/06/5d/305323ba86b284e6fcb0d842d6adaa2999035f70f8c38a9b6d21ad28c3d4/pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl + name: pyzmq + version: 27.1.0 + sha256: 226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86 + requires_dist: + - cffi ; implementation_name == 'pypy' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/23/6d/d8d92a0eb270a925c9b4dd039c0b4dc10abc2fcbc48331788824ef113935/pyzmq-27.1.0-cp311-cp311-win_amd64.whl + name: pyzmq + version: 27.1.0 + sha256: 190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97 + requires_dist: + - cffi ; implementation_name == 'pypy' + requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl name: pyzmq version: 27.1.0 @@ -4604,6 +8877,13 @@ packages: requires_dist: - cffi ; implementation_name == 'pypy' requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/b1/c4/2a6fe5111a01005fc7af3878259ce17684fabb8852815eda6225620f3c59/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl + name: pyzmq + version: 27.1.0 + sha256: 5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e + requires_dist: + - cffi ; implementation_name == 'pypy' + requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl name: pyzmq version: 27.1.0 @@ -4618,47 +8898,56 @@ packages: requires_dist: - cffi ; implementation_name == 'pypy' requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - sha256: 2d6d0c026902561ed77cd646b5021aef2d4db22e57a5b0178dfc669231e06d2c - md5: 283b96675859b20a825f8fa30f311446 +- pypi: https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl + name: questionary + version: 2.1.1 + sha256: a51af13f345f1cdea62347589fbb6df3b290306ab8930713bfae4d475a7d4a59 + requires_dist: + - prompt-toolkit>=2.0,<4.0 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/93/f7/d00d9b4a0313a6be3a3e0818e6375e15da6d7076f4ae47d1324e7ca986a1/radon-6.0.1-py2.py3-none-any.whl + name: radon + version: 6.0.1 + sha256: 632cc032364a6f8bb1010a2f6a12d0f14bc7e5ede76585ef29dc0cecf4cd8859 + requires_dist: + - mando>=0.6,<0.8 + - colorama==0.4.1 ; python_full_version < '3.5' + - colorama>=0.4.1 ; python_full_version >= '3.5' + - tomli>=2.0.1 ; extra == 'toml' +- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 + md5: d7d95fc8287ea7bf33e0e7116d2b95ec depends: - - libgcc >=13 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 - ncurses >=6.5,<7.0a0 license: GPL-3.0-only license_family: GPL purls: [] - size: 282480 - timestamp: 1740379431762 -- conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda - sha256: 53017e80453c4c1d97aaf78369040418dea14cf8f46a2fa999f31bd70b36c877 - md5: 342570f8e02f2f022147a7f841475784 + size: 345073 + timestamp: 1765813471974 +- conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda + sha256: 4614af680aa0920e82b953fece85a03007e0719c3399f13d7de64176874b80d5 + md5: eefd65452dfe7cce476a519bece46704 depends: + - __osx >=10.13 - ncurses >=6.5,<7.0a0 license: GPL-3.0-only license_family: GPL purls: [] - size: 256712 - timestamp: 1740379577668 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda - sha256: 7db04684d3904f6151eff8673270922d31da1eea7fa73254d01c437f49702e34 - md5: 63ef3f6e6d6d5c589e64f11263dc5676 + size: 317819 + timestamp: 1765813692798 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + sha256: a77010528efb4b548ac2a4484eaf7e1c3907f2aec86123ed9c5212ae44502477 + md5: f8381319127120ce51e081dce4865cf4 depends: + - __osx >=11.0 - ncurses >=6.5,<7.0a0 license: GPL-3.0-only license_family: GPL purls: [] - size: 252359 - timestamp: 1740379663071 -- pypi: https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl - name: readme-renderer - version: '44.0' - sha256: 2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151 - requires_dist: - - nh3>=0.2.14 - - docutils>=0.21.2 - - pygments>=2.5.1 - - cmarkgfm>=0.8.0 ; extra == 'md' - requires_python: '>=3.9' + size: 313930 + timestamp: 1765813902568 - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl name: referencing version: 0.37.0 @@ -4680,12 +8969,16 @@ packages: - pysocks>=1.5.6,!=1.5.7 ; extra == 'socks' - chardet>=3.0.2,<6 ; extra == 'use-chardet-on-py3' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/af/63/ac52b32b33ae62f2076ed5c4f6b00e065e3ccbb2063e9a2e813b2bfc95bf/restructuredtext_lint-2.0.2-py3-none-any.whl - name: restructuredtext-lint - version: 2.0.2 - sha256: 374c0d3e7e0867b2335146a145343ac619400623716b211b9a010c94426bbed7 - requires_dist: - - docutils>=0.11,<1.0 +- pypi: https://files.pythonhosted.org/packages/57/4d/a7545bf6c62b0dbe5795f22ea9e88cc070fdced5c34663ebc5bed2f610c0/returns-0.26.0-py3-none-any.whl + name: returns + version: 0.26.0 + sha256: 7cae94c730d6c56ffd9d0f583f7a2c0b32cfe17d141837150c8e6cff3eb30d71 + requires_dist: + - hypothesis>=6.136,<7.0 ; extra == 'check-laws' + - mypy>=1.12,<1.18 ; extra == 'compatible-mypy' + - pytest>=8.0,<9.0 ; extra == 'check-laws' + - typing-extensions>=4.0,<5.0 + requires_python: '>=3.10,<4.0' - pypi: https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl name: rfc3339-validator version: 0.1.4 @@ -4706,62 +8999,202 @@ packages: - lark>=1.2.2 - pytest>=8.3.5 ; extra == 'testing' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl - name: roman-numerals-py - version: 3.1.0 - sha256: 9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c - requires_dist: - - mypy==1.15.0 ; extra == 'lint' - - ruff==0.9.7 ; extra == 'lint' - - pyright==1.1.394 ; extra == 'lint' - - pytest>=8 ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/3c/6b/0229d3bed4ddaa409e6d90b0ae967ed4380e4bdd0dad6e59b92c17d42457/rpds_py-0.29.0-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/4d/6e/f964e88b3d2abee2a82c1ac8366da848fce1c6d834dc2132c3fda3970290/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl + name: rpds-py + version: 0.30.0 + sha256: a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/94/ba/24e5ebb7c1c82e74c4e4f33b2112a5573ddc703915b13a073737b59b86e0/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl + name: rpds-py + version: 0.30.0 + sha256: dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: rpds-py + version: 0.30.0 + sha256: 9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl + name: rpds-py + version: 0.30.0 + sha256: f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl name: rpds-py - version: 0.29.0 - sha256: 6410e66f02803600edb0b1889541f4b5cc298a5ccda0ad789cc50ef23b54813e + version: 0.30.0 + sha256: 806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b3/b3/0860cdd012291dc21272895ce107f1e98e335509ba986dd83d72658b82b9/rpds_py-0.29.0-cp313-cp313-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/f8/1e/372195d326549bb51f0ba0f2ecb9874579906b97e08880e7a65c3bef1a99/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: rpds-py - version: 0.29.0 - sha256: 521807963971a23996ddaf764c682b3e46459b3c58ccd79fefbe16718db43154 + version: 0.30.0 + sha256: 33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/b9/42/555b4ee17508beafac135c8b450816ace5a96194ce97fefc49d58e5652ea/rpds_py-0.29.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/fa/5b/e7b7aa136f28462b344e652ee010d4de26ee9fd16f1bfd5811f5153ccf89/rpds_py-0.30.0-cp311-cp311-win_amd64.whl name: rpds-py - version: 0.29.0 - sha256: de73e40ebc04dd5d9556f50180395322193a78ec247e637e741c1b954810f295 + version: 0.30.0 + sha256: a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/fd/d9/c5de60d9d371bbb186c3e9bf75f4fc5665e11117a25a06a6b2e0afb7380e/rpds_py-0.29.0-cp313-cp313-macosx_10_12_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl name: rpds-py - version: 0.29.0 - sha256: 1585648d0760b88292eecab5181f5651111a69d90eff35d6b78aa32998886a61 + version: 0.30.0 + sha256: e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/13/ac/9b9fe63716af8bdfddfacd0882bc1586f29985d3b988b3c62ddce2e202c3/ruff-0.14.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/b1/d8/0fab9f8842b83b1a9c2bf81b85063f65e93fb512e60effa95b0be49bfc54/ruff-0.15.4-py3-none-macosx_11_0_arm64.whl name: ruff - version: 0.14.6 - sha256: 167843a6f78680746d7e226f255d920aeed5e4ad9c03258094a2d49d3028b105 + version: 0.15.4 + sha256: a4386ba2cd6c0f4ff75252845906acc7c7c8e1ac567b7bc3d373686ac8c222ba requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/36/6a/ad66d0a3315d6327ed6b01f759d83df3c4d5f86c30462121024361137b6a/ruff-0.14.6-py3-none-macosx_10_12_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/ce/5d/6a1f271f6e31dffb31855996493641edc3eef8077b883eaf007a2f1c2976/ruff-0.15.4-py3-none-macosx_10_12_x86_64.whl name: ruff - version: 0.14.6 - sha256: 9f7539ea257aa4d07b7ce87aed580e485c40143f2473ff2f2b75aee003186004 + version: 0.15.4 + sha256: 5a1632c66672b8b4d3e1d1782859e98d6e0b4e70829530666644286600a33992 requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/a3/9d/dae6db96df28e0a15dea8e986ee393af70fc97fd57669808728080529c37/ruff-0.14.6-py3-none-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/d0/a8/c688ef7e29983976820d18710f955751d9f4d4eb69df658af3d006e2ba3e/ruff-0.15.4-py3-none-win_amd64.whl name: ruff - version: 0.14.6 - sha256: 7f6007e55b90a2a7e93083ba48a9f23c3158c433591c33ee2e99a49b889c6332 + version: 0.15.4 + sha256: 04196ad44f0df220c2ece5b0e959c2f37c777375ec744397d21d15b50a75264f requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/fb/02/82240553b77fd1341f80ebb3eaae43ba011c7a91b4224a9f317d8e6591af/ruff-0.14.6-py3-none-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/ff/90/bf134f4c1e5243e62690e09d63c55df948a74084c8ac3e48a88468314da6/ruff-0.15.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: ruff - version: 0.14.6 - sha256: 390e6480c5e3659f8a4c8d6a0373027820419ac14fa0d2713bd8e6c3e125b8b9 + version: 0.15.4 + sha256: 451a2e224151729b3b6c9ffb36aed9091b2996fe4bdbd11f47e27d8f2e8888ec requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/64/7c/d8a343b0a622987335a1ac848084079c47c21e44fcc450f9c145b11a56f6/scipp-25.11.0-cp313-cp313-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/12/0d/3f98a936a30bff4a460b51b9f85c4d994f94249930b2d8bedeb8111a359e/scipp-25.12.0-cp311-cp311-macosx_11_0_x86_64.whl + name: scipp + version: 25.12.0 + sha256: 6391dc46739006e1e4eb7f2fcbcdbdd40f11a3cbae53e93b63b5ba32909bd792 + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/18/5c/bc0ca94bff65fe0d206a369b54625f8ec7852dfd1d835174692026f34df9/scipp-25.12.0-cp313-cp313-macosx_11_0_arm64.whl + name: scipp + version: 25.12.0 + sha256: 0285c91b202dea9aeb18f29d73ff135208a19b2068cd30e17ee81fc435b1943c + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/4e/b6/ffe0bb67cec66cd450acff599bb07507bbf5ffda1a3a15dd2d8dbe7a6da7/scipp-25.12.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: scipp + version: 25.12.0 + sha256: 9ec0200eeb660965056b27f5f05505a961d8921b78d0a92c04743d1c22ce7203 + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/6a/3a/ab0eb61593569d5a0d080002e4b8c0998cb1116d8710781b7225c304b880/scipp-25.12.0-cp311-cp311-macosx_11_0_arm64.whl + name: scipp + version: 25.12.0 + sha256: e27082f5bd3655f15479ce87be495235b9bcd9b5db654a7219261be0c6117b31 + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/94/98/aa2d4b9d28969cc7f62409f9f9fc5b5a853af651255eba03e9bee8546dd9/scipp-25.12.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: scipp + version: 25.12.0 + sha256: e5694bef45299c4813ee2fe863fab600c3b0f5e13e2735072dbbb5cf1804d0e0 + requires_dist: + - numpy>=2 + - pytest ; extra == 'test' + - matplotlib ; extra == 'test' + - beautifulsoup4 ; extra == 'test' + - ipython ; extra == 'test' + - h5py ; extra == 'extra' + - scipy>=1.7.0 ; extra == 'extra' + - graphviz ; extra == 'extra' + - pooch ; extra == 'extra' + - plopp ; extra == 'extra' + - matplotlib ; extra == 'extra' + - scipp[extra] ; extra == 'all' + - ipympl ; extra == 'all' + - ipython ; extra == 'all' + - ipywidgets ; extra == 'all' + - jupyterlab ; extra == 'all' + - jupyterlab-widgets ; extra == 'all' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/bd/75/6a3786de6645ac2ccd94fbf83c59cc6b929bfa3a89cb62c8cb3be4de0606/scipp-25.12.0-cp311-cp311-win_amd64.whl name: scipp - version: 25.11.0 - sha256: 9b082fc7fd29919b4fee007f63db265176becb06c669a4b709feb741b76c612a + version: 25.12.0 + sha256: aee5f585232e2a7a664f57bb9695164715271b74896704e7ee8a669dd7b06008 requires_dist: - - numpy>=1.20 + - numpy>=2 - pytest ; extra == 'test' - matplotlib ; extra == 'test' - beautifulsoup4 ; extra == 'test' @@ -4782,12 +9215,12 @@ packages: - nodejs ; extra == 'all' - pythreejs ; extra == 'all' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/71/f2/18d5be10ac890ce7490451eb55d41bf9d96e481751362a30ed1a8bc176fa/scipp-25.11.0-cp313-cp313-macosx_11_0_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/e5/22/75e119e0a200914f88f121cd956e1eb7f72c8ace4b63171f52ba0334d142/scipp-25.12.0-cp313-cp313-macosx_11_0_x86_64.whl name: scipp - version: 25.11.0 - sha256: fd7788e3ea3dd5334ed7fb53a249413469edc5d836ca5d68b1f271691cf11269 + version: 25.12.0 + sha256: 27ebc37f3b7e20c9dca9cf1a0ac53c4ffaea31c02dfc8ba2b5aa008a252cbcba requires_dist: - - numpy>=1.20 + - numpy>=2 - pytest ; extra == 'test' - matplotlib ; extra == 'test' - beautifulsoup4 ; extra == 'test' @@ -4808,12 +9241,12 @@ packages: - nodejs ; extra == 'all' - pythreejs ; extra == 'all' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/77/34/1956aed61c4abb91926f9513330afac4654cc2a711ecb73085dc4e2e5c1d/scipp-25.11.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/eb/d1/b3cd2733a96a36c54c36889b2cfdd0331c1e5b57fa1757485a22d0ec3142/scipp-25.12.0-cp313-cp313-win_amd64.whl name: scipp - version: 25.11.0 - sha256: 3e91c8093dc83d433a2e53708561228a06a7e34d8775a20118d391f5b891a6e6 + version: 25.12.0 + sha256: 015db5035749750cf026db56fe537af10f159dc3cd0f51f0ea9f4ecc3a7a5da8 requires_dist: - - numpy>=1.20 + - numpy>=2 - pytest ; extra == 'test' - matplotlib ; extra == 'test' - beautifulsoup4 ; extra == 'test' @@ -4834,38 +9267,188 @@ packages: - nodejs ; extra == 'all' - pythreejs ; extra == 'all' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/f6/f3/9d1bb423a2dc0bbebfc98191095dd410a1268397b9c692d76a3ea971c790/scipp-25.11.0-cp313-cp313-win_amd64.whl - name: scipp - version: 25.11.0 - sha256: d44d2aa3f6634ac750a126e50a740c487aa8a2181fcb03764b29ddceeea611cf +- pypi: https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: scipy + version: 1.17.1 + sha256: 43af8d1f3bea642559019edfe64e9b11192a8978efbd1539d7bc2aaa23d92de4 + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl + name: scipy + version: 1.17.1 + sha256: 37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448 + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/76/27/07ee1b57b65e92645f219b37148a7e7928b82e2b5dbeccecb4dff7c64f0b/scipy-1.17.1-cp313-cp313-macosx_10_14_x86_64.whl + name: scipy + version: 1.17.1 + sha256: 5e3c5c011904115f88a39308379c17f91546f77c1667cea98739fe0fccea804c + requires_dist: + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/95/da/0d1df507cf574b3f224ccc3d45244c9a1d732c81dcb26b1e8a766ae271a8/scipy-1.17.1-cp311-cp311-win_amd64.whl + name: scipy + version: 1.17.1 + sha256: d30e57c72013c2a4fe441c2fcb8e77b14e152ad48b5464858e07e2ad9fbfceff requires_dist: - - numpy>=1.20 - - pytest ; extra == 'test' - - matplotlib ; extra == 'test' - - beautifulsoup4 ; extra == 'test' - - ipython ; extra == 'test' - - h5py ; extra == 'extra' - - scipy>=1.7.0 ; extra == 'extra' - - graphviz ; extra == 'extra' - - pooch ; extra == 'extra' - - plopp ; extra == 'extra' - - matplotlib ; extra == 'extra' - - scipp[extra] ; extra == 'all' - - ipympl ; extra == 'all' - - ipython ; extra == 'all' - - ipywidgets ; extra == 'all' - - jupyterlab ; extra == 'all' - - jupyterlab-widgets ; extra == 'all' - - jupyter-nbextensions-configurator ; extra == 'all' - - nodejs ; extra == 'all' - - pythreejs ; extra == 'all' + - numpy>=1.26.4,<2.7 + - pytest>=8.0.0 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest-xdist ; extra == 'test' + - asv ; extra == 'test' + - mpmath ; extra == 'test' + - gmpy2 ; extra == 'test' + - threadpoolctl ; extra == 'test' + - scikit-umfpack ; extra == 'test' + - pooch ; extra == 'test' + - hypothesis>=6.30 ; extra == 'test' + - array-api-strict>=2.3.1 ; extra == 'test' + - cython ; extra == 'test' + - meson ; extra == 'test' + - ninja ; sys_platform != 'emscripten' and extra == 'test' + - sphinx>=5.0.0,<8.2.0 ; extra == 'doc' + - intersphinx-registry ; extra == 'doc' + - pydata-sphinx-theme>=0.15.2 ; extra == 'doc' + - sphinx-copybutton ; extra == 'doc' + - sphinx-design>=0.4.0 ; extra == 'doc' + - matplotlib>=3.5 ; extra == 'doc' + - numpydoc ; extra == 'doc' + - jupytext ; extra == 'doc' + - myst-nb>=1.2.0 ; extra == 'doc' + - pooch ; extra == 'doc' + - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' + - jupyterlite-pyodide-kernel ; extra == 'doc' + - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' + - mypy==1.10.0 ; extra == 'dev' + - typing-extensions ; extra == 'dev' + - types-psutil ; extra == 'dev' + - pycodestyle ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' + - cython-lint>=0.12.2 ; extra == 'dev' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/21/f6/4bfb5695d8941e5c570a04d9fcd0d36bce7511b7d78e6e75c8f9791f82d0/scipy-1.16.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/df/75/b4ce781849931fef6fd529afa6b63711d5a733065722d0c3e2724af9e40a/scipy-1.17.1-cp311-cp311-macosx_10_14_x86_64.whl name: scipy - version: 1.16.3 - sha256: 7dc1360c06535ea6116a2220f760ae572db9f661aba2d88074fe30ec2aa1ff88 + version: 1.17.1 + sha256: 1f95b894f13729334fb990162e911c9e5dc1ab390c58aa6cbecb389c5b5e28ec requires_dist: - - numpy>=1.25.2,<2.6 + - numpy>=1.26.4,<2.7 - pytest>=8.0.0 ; extra == 'test' - pytest-cov ; extra == 'test' - pytest-timeout ; extra == 'test' @@ -4894,22 +9477,22 @@ packages: - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' - jupyterlite-pyodide-kernel ; extra == 'doc' - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' - mypy==1.10.0 ; extra == 'dev' - typing-extensions ; extra == 'dev' - types-psutil ; extra == 'dev' - pycodestyle ; extra == 'dev' - - ruff>=0.0.292 ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' - cython-lint>=0.12.2 ; extra == 'dev' - - rich-click ; extra == 'dev' - - doit>=0.36.0 ; extra == 'dev' - - pydevtool ; extra == 'dev' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/44/13/7e63cfba8a7452eb756306aa2fd9b37a29a323b672b964b4fdeded9a3f21/scipy-1.16.3-cp313-cp313-macosx_12_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/ec/ae/db19f8ab842e9b724bf5dbb7db29302a91f1e55bc4d04b1025d6d605a2c5/scipy-1.17.1-cp313-cp313-macosx_12_0_arm64.whl name: scipy - version: 1.16.3 - sha256: 16b8bc35a4cc24db80a0ec836a9286d0e31b2503cb2fd7ff7fb0e0374a97081d + version: 1.17.1 + sha256: 6fac755ca3d2c3edcb22f479fceaa241704111414831ddd3bc6056e18516892f requires_dist: - - numpy>=1.25.2,<2.6 + - numpy>=1.26.4,<2.7 - pytest>=8.0.0 ; extra == 'test' - pytest-cov ; extra == 'test' - pytest-timeout ; extra == 'test' @@ -4938,22 +9521,22 @@ packages: - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' - jupyterlite-pyodide-kernel ; extra == 'doc' - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' - mypy==1.10.0 ; extra == 'dev' - typing-extensions ; extra == 'dev' - types-psutil ; extra == 'dev' - pycodestyle ; extra == 'dev' - - ruff>=0.0.292 ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' - cython-lint>=0.12.2 ; extra == 'dev' - - rich-click ; extra == 'dev' - - doit>=0.36.0 ; extra == 'dev' - - pydevtool ; extra == 'dev' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/72/f1/57e8327ab1508272029e27eeef34f2302ffc156b69e7e233e906c2a5c379/scipy-1.16.3-cp313-cp313-macosx_10_14_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl name: scipy - version: 1.16.3 - sha256: d2ec56337675e61b312179a1ad124f5f570c00f920cc75e1000025451b88241c + version: 1.17.1 + sha256: 581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464 requires_dist: - - numpy>=1.25.2,<2.6 + - numpy>=1.26.4,<2.7 - pytest>=8.0.0 ; extra == 'test' - pytest-cov ; extra == 'test' - pytest-timeout ; extra == 'test' @@ -4982,22 +9565,22 @@ packages: - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' - jupyterlite-pyodide-kernel ; extra == 'doc' - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' - mypy==1.10.0 ; extra == 'dev' - typing-extensions ; extra == 'dev' - types-psutil ; extra == 'dev' - pycodestyle ; extra == 'dev' - - ruff>=0.0.292 ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' - cython-lint>=0.12.2 ; extra == 'dev' - - rich-click ; extra == 'dev' - - doit>=0.36.0 ; extra == 'dev' - - pydevtool ; extra == 'dev' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/cd/01/1204382461fcbfeb05b6161b594f4007e78b6eba9b375382f79153172b4d/scipy-1.16.3-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/f7/58/bccc2861b305abdd1b8663d6130c0b3d7cc22e8d86663edbc8401bfd40d4/scipy-1.17.1-cp311-cp311-macosx_12_0_arm64.whl name: scipy - version: 1.16.3 - sha256: 062246acacbe9f8210de8e751b16fc37458213f124bef161a5a02c7a39284304 + version: 1.17.1 + sha256: e18f12c6b0bc5a592ed23d3f7b891f68fd7f8241d69b7883769eb5d5dfb52696 requires_dist: - - numpy>=1.25.2,<2.6 + - numpy>=1.26.4,<2.7 - pytest>=8.0.0 ; extra == 'test' - pytest-cov ; extra == 'test' - pytest-timeout ; extra == 'test' @@ -5026,30 +9609,29 @@ packages: - jupyterlite-sphinx>=0.19.1 ; extra == 'doc' - jupyterlite-pyodide-kernel ; extra == 'doc' - linkify-it-py ; extra == 'doc' + - tabulate ; extra == 'doc' + - click<8.3.0 ; extra == 'dev' + - spin ; extra == 'dev' - mypy==1.10.0 ; extra == 'dev' - typing-extensions ; extra == 'dev' - types-psutil ; extra == 'dev' - pycodestyle ; extra == 'dev' - - ruff>=0.0.292 ; extra == 'dev' + - ruff>=0.12.0 ; extra == 'dev' - cython-lint>=0.12.2 ; extra == 'dev' - - rich-click ; extra == 'dev' - - doit>=0.36.0 ; extra == 'dev' - - pydevtool ; extra == 'dev' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl name: send2trash - version: 1.8.3 - sha256: 0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9 - requires_dist: - - pyobjc-framework-cocoa ; sys_platform == 'darwin' and extra == 'nativelib' - - pywin32 ; sys_platform == 'win32' and extra == 'nativelib' - - pyobjc-framework-cocoa ; sys_platform == 'darwin' and extra == 'objc' - - pywin32 ; sys_platform == 'win32' and extra == 'win32' - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*' -- pypi: https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl + version: 2.1.0 + sha256: 0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c + requires_dist: + - pytest>=8 ; extra == 'test' + - pywin32>=305 ; sys_platform == 'win32' and extra == 'nativelib' + - pyobjc>=9.0 ; sys_platform == 'darwin' and extra == 'nativelib' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/e1/c6/76dc613121b793286a3f91621d7b75a2b493e0390ddca50f11993eadf192/setuptools-82.0.0-py3-none-any.whl name: setuptools - version: 80.9.0 - sha256: 062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 + version: 82.0.0 + sha256: 70b18734b607bd1da571d097d236cfcfacaf01de45717d59e6e04b96877532e0 requires_dist: - pytest>=6,!=8.1.* ; extra == 'test' - virtualenv>=13.0.0 ; extra == 'test' @@ -5095,23 +9677,14 @@ packages: - more-itertools ; extra == 'core' - pytest-checkdocs>=2.4 ; extra == 'check' - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' - - ruff>=0.8.0 ; sys_platform != 'cygwin' and extra == 'check' + - ruff>=0.13.0 ; sys_platform != 'cygwin' and extra == 'check' - pytest-cov ; extra == 'cover' - pytest-enabler>=2.2 ; extra == 'enabler' - pytest-mypy ; extra == 'type' - - mypy==1.14.* ; extra == 'type' + - mypy==1.18.* ; extra == 'type' - importlib-metadata>=7.0.2 ; python_full_version < '3.10' and extra == 'type' - jaraco-develop>=7.21 ; sys_platform != 'cygwin' and extra == 'type' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c0/ba/daf16c2d1965bf6237fb696639e3e93645ac6801f7dcaf9ec694a74e9326/setuptools_git_versioning-2.1.0-py3-none-any.whl - name: setuptools-git-versioning - version: 2.1.0 - sha256: 09a15cbb9a00884e91a3591a4c9ec1ff93c24b1b4a40de39a44815196beb7ebf - requires_dist: - - packaging - - setuptools - - tomli>=2.0.1 ; python_full_version < '3.11' - requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl name: simple-websocket version: 1.1.0 @@ -5129,213 +9702,37 @@ packages: version: 1.17.0 sha256: 4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' -- pypi: https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl - name: sniffio - version: 1.3.1 - sha256: 2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 +- pypi: https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl + name: smmap + version: 5.0.2 + sha256: b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl - name: snowballstemmer - version: 3.0.1 - sha256: 6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 - requires_python: '!=3.0.*,!=3.1.*,!=3.2.*' -- pypi: https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl name: soupsieve - version: '2.8' - sha256: 0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl - name: sphinx - version: 8.2.3 - sha256: 4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3 - requires_dist: - - sphinxcontrib-applehelp>=1.0.7 - - sphinxcontrib-devhelp>=1.0.6 - - sphinxcontrib-htmlhelp>=2.0.6 - - sphinxcontrib-jsmath>=1.0.1 - - sphinxcontrib-qthelp>=1.0.6 - - sphinxcontrib-serializinghtml>=1.1.9 - - jinja2>=3.1 - - pygments>=2.17 - - docutils>=0.20,<0.22 - - snowballstemmer>=2.2 - - babel>=2.13 - - alabaster>=0.7.14 - - imagesize>=1.3 - - requests>=2.30.0 - - roman-numerals-py>=1.0.0 - - packaging>=23.0 - - colorama>=0.4.6 ; sys_platform == 'win32' - - sphinxcontrib-websupport ; extra == 'docs' - - ruff==0.9.9 ; extra == 'lint' - - mypy==1.15.0 ; extra == 'lint' - - sphinx-lint>=0.9 ; extra == 'lint' - - types-colorama==0.4.15.20240311 ; extra == 'lint' - - types-defusedxml==0.7.0.20240218 ; extra == 'lint' - - types-docutils==0.21.0.20241128 ; extra == 'lint' - - types-pillow==10.2.0.20240822 ; extra == 'lint' - - types-pygments==2.19.0.20250219 ; extra == 'lint' - - types-requests==2.32.0.20241016 ; extra == 'lint' - - types-urllib3==1.26.25.14 ; extra == 'lint' - - pyright==1.1.395 ; extra == 'lint' - - pytest>=8.0 ; extra == 'lint' - - pypi-attestations==0.0.21 ; extra == 'lint' - - betterproto==2.0.0b6 ; extra == 'lint' - - pytest>=8.0 ; extra == 'test' - - pytest-xdist[psutil]>=3.4 ; extra == 'test' - - defusedxml>=0.7.1 ; extra == 'test' - - cython>=3.0 ; extra == 'test' - - setuptools>=70.0 ; extra == 'test' - - typing-extensions>=4.9 ; extra == 'test' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/05/f2/9657c98a66973b7c35bfd48ba65d1922860de9598fbb535cd96e3f58a908/sphinx_autodoc_typehints-3.5.2-py3-none-any.whl - name: sphinx-autodoc-typehints - version: 3.5.2 - sha256: 0accd043619f53c86705958e323b419e41667917045ac9215d7be1b493648d8c - requires_dist: - - sphinx>=8.2.3 - - furo>=2025.9.25 ; extra == 'docs' - - covdefaults>=2.3 ; extra == 'testing' - - coverage>=7.10.7 ; extra == 'testing' - - defusedxml>=0.7.1 ; extra == 'testing' - - diff-cover>=9.7.1 ; extra == 'testing' - - pytest-cov>=7 ; extra == 'testing' - - pytest>=8.4.2 ; extra == 'testing' - - sphobjinv>=2.3.1.3 ; extra == 'testing' - - typing-extensions>=4.15 ; extra == 'testing' - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/51/9e/c41d68be04eef5b6202b468e0f90faf0c469f3a03353f2a218fd78279710/sphinx_book_theme-1.1.4-py3-none-any.whl - name: sphinx-book-theme - version: 1.1.4 - sha256: 843b3f5c8684640f4a2d01abd298beb66452d1b2394cd9ef5be5ebd5640ea0e1 - requires_dist: - - sphinx>=6.1 - - pydata-sphinx-theme==0.15.4 - - pre-commit ; extra == 'code-style' - - ablog ; extra == 'doc' - - ipywidgets ; extra == 'doc' - - folium ; extra == 'doc' - - numpy ; extra == 'doc' - - matplotlib ; extra == 'doc' - - numpydoc ; extra == 'doc' - - myst-nb ; extra == 'doc' - - nbclient ; extra == 'doc' - - pandas ; extra == 'doc' - - plotly ; extra == 'doc' - - sphinx-design ; extra == 'doc' - - sphinx-examples ; extra == 'doc' - - sphinx-copybutton ; extra == 'doc' - - sphinx-tabs ; extra == 'doc' - - sphinx-togglebutton ; extra == 'doc' - - sphinx-thebe ; extra == 'doc' - - sphinxcontrib-bibtex ; extra == 'doc' - - sphinxcontrib-youtube ; extra == 'doc' - - sphinxext-opengraph ; extra == 'doc' - - beautifulsoup4 ; extra == 'test' - - coverage ; extra == 'test' - - defusedxml ; extra == 'test' - - myst-nb ; extra == 'test' - - pytest ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-regressions ; extra == 'test' - - sphinx-thebe ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/77/c7/52b48aec16b26c52aba854d03a3a31e0681150301dac1bea2243645a69e7/sphinx_gallery-0.19.0-py3-none-any.whl - name: sphinx-gallery - version: 0.19.0 - sha256: 4c28751973f81769d5bbbf5e4ebaa0dc49dff8c48eb7f11131eb5f6e4aa25f0e - requires_dist: - - pillow - - sphinx>=5 - - sphinxcontrib-video ; extra == 'animations' - - absl-py ; extra == 'dev' - - graphviz ; extra == 'dev' - - intersphinx-registry ; extra == 'dev' - - ipython ; extra == 'dev' - - joblib ; extra == 'dev' - - jupyterlite-sphinx>=0.17.1 ; extra == 'dev' - - lxml ; extra == 'dev' - - matplotlib ; extra == 'dev' - - numpy ; extra == 'dev' - - packaging ; extra == 'dev' - - plotly ; extra == 'dev' - - pydata-sphinx-theme ; extra == 'dev' - - pytest ; extra == 'dev' - - pytest-coverage ; extra == 'dev' - - seaborn ; extra == 'dev' - - sphinxcontrib-video ; extra == 'dev' - - statsmodels ; extra == 'dev' - - jupyterlite-sphinx ; extra == 'jupyterlite' - - joblib ; extra == 'parallel' - - numpy ; extra == 'recommender' - - graphviz ; extra == 'show-api-usage' - - memory-profiler ; extra == 'show-memory' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl - name: sphinxcontrib-applehelp - version: 2.0.0 - sha256: 4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 - requires_dist: - - ruff==0.5.5 ; extra == 'lint' - - mypy ; extra == 'lint' - - types-docutils ; extra == 'lint' - - sphinx>=5 ; extra == 'standalone' - - pytest ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl - name: sphinxcontrib-devhelp - version: 2.0.0 - sha256: aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2 - requires_dist: - - ruff==0.5.5 ; extra == 'lint' - - mypy ; extra == 'lint' - - types-docutils ; extra == 'lint' - - sphinx>=5 ; extra == 'standalone' - - pytest ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl - name: sphinxcontrib-htmlhelp - version: 2.1.0 - sha256: 166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8 - requires_dist: - - ruff==0.5.5 ; extra == 'lint' - - mypy ; extra == 'lint' - - types-docutils ; extra == 'lint' - - sphinx>=5 ; extra == 'standalone' - - pytest ; extra == 'test' - - html5lib ; extra == 'test' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl - name: sphinxcontrib-jsmath - version: 1.0.1 - sha256: 2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 - requires_dist: - - pytest ; extra == 'test' - - flake8 ; extra == 'test' - - mypy ; extra == 'test' - requires_python: '>=3.5' -- pypi: https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl - name: sphinxcontrib-qthelp - version: 2.0.0 - sha256: b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb - requires_dist: - - ruff==0.5.5 ; extra == 'lint' - - mypy ; extra == 'lint' - - types-docutils ; extra == 'lint' - - sphinx>=5 ; extra == 'standalone' - - pytest ; extra == 'test' - - defusedxml>=0.7.1 ; extra == 'test' + version: 2.8.3 + sha256: ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl - name: sphinxcontrib-serializinghtml - version: 2.0.0 - sha256: 6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 - requires_dist: - - ruff==0.5.5 ; extra == 'lint' - - mypy ; extra == 'lint' - - types-docutils ; extra == 'lint' - - sphinx>=5 ; extra == 'standalone' - - pytest ; extra == 'test' +- pypi: https://files.pythonhosted.org/packages/3e/17/1f31d8562e6f970d64911f1abc330d233bc0c0601411cf7e19c1292be6da/spdx_headers-1.5.1-py3-none-any.whl + name: spdx-headers + version: 1.5.1 + sha256: 73bcb1ed087824b55ccaa497d03d8f0f0b0eaf30e5f0f7d5bbd29d2c4fe78fcf + requires_dist: + - chardet>=5.2.0 + - requests>=2.32.3 + - black>=23.0.0 ; extra == 'dev' + - build>=0.10.0 ; extra == 'dev' + - hatch>=1.9.0 ; extra == 'dev' + - isort>=5.12.0 ; extra == 'dev' + - mypy>=1.0.0 ; extra == 'dev' + - pre-commit>=4.3.0 ; extra == 'dev' + - pytest-cov>=4.0.0 ; extra == 'dev' + - pytest>=7.0.0 ; extra == 'dev' + - ruff>=0.5.0 ; extra == 'dev' + - twine>=4.0.0 ; extra == 'dev' + - types-requests>=2.31.0.6 ; extra == 'dev' + - pytest-cov>=4.0.0 ; extra == 'test' + - pytest-mock>=3.10.0 ; extra == 'test' + - pytest>=7.0.0 ; extra == 'test' requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl name: stack-data @@ -5350,11 +9747,13 @@ packages: - pygments ; extra == 'tests' - littleutils ; extra == 'tests' - cython ; extra == 'tests' -- pypi: https://files.pythonhosted.org/packages/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.0-py3-none-any.whl - name: stevedore - version: 5.6.0 - sha256: 4a36dccefd7aeea0c70135526cecb7766c4c84c473b1af68db23d541b6dc1820 - requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl + name: tabulate + version: 0.9.0 + sha256: 024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f + requires_dist: + - wcwidth ; extra == 'widechars' + requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl name: terminado version: 0.18.1 @@ -5383,110 +9782,119 @@ packages: - pytest ; extra == 'test' - ruff ; extra == 'test' requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda - sha256: 1544760538a40bcd8ace2b1d8ebe3eb5807ac268641f8acdc18c69c5ebfeaf64 - md5: 86bc20552bf46075e3d92b67f089172d +- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac + md5: cffd3bdd58090148f4cfcd831f4b26ab depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - libzlib >=1.3.1,<2.0a0 constrains: - xorg-libx11 >=1.8.12,<2.0a0 license: TCL license_family: BSD purls: [] - size: 3284905 - timestamp: 1763054914403 -- conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_3.conda - sha256: 0d0b6cef83fec41bc0eb4f3b761c4621b7adfb14378051a8177bd9bb73d26779 - md5: bd9f1de651dbd80b51281c694827f78f + size: 3301196 + timestamp: 1769460227866 +- conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda + sha256: 7f0d9c320288532873e2d8486c331ec6d87919c9028208d3f6ac91dc8f99a67b + md5: 6e6efb7463f8cef69dbcb4c2205bf60e depends: - __osx >=10.13 - libzlib >=1.3.1,<2.0a0 license: TCL license_family: BSD purls: [] - size: 3262702 - timestamp: 1763055085507 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_3.conda - sha256: ad0c67cb03c163a109820dc9ecf77faf6ec7150e942d1e8bb13e5d39dc058ab7 - md5: a73d54a5abba6543cb2f0af1bfbd6851 + size: 3282953 + timestamp: 1769460532442 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + sha256: 799cab4b6cde62f91f750149995d149bc9db525ec12595e8a1d91b9317f038b3 + md5: a9d86bc62f39b94c4661716624eb21b0 depends: - __osx >=11.0 - libzlib >=1.3.1,<2.0a0 license: TCL license_family: BSD purls: [] - size: 3125484 - timestamp: 1763055028377 -- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_3.conda - sha256: 4581f4ffb432fefa1ac4f85c5682cc27014bcd66e7beaa0ee330e927a7858790 - md5: 7cb36e506a7dba4817970f8adb6396f9 + size: 3127137 + timestamp: 1769460817696 +- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + sha256: 0e79810fae28f3b69fe7391b0d43f5474d6bd91d451d5f2bde02f55ae481d5e3 + md5: 0481bfd9814bf525bd4b3ee4b51494c4 depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: TCL license_family: BSD purls: [] - size: 3472313 - timestamp: 1763055164278 -- pypi: https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl - name: toml - version: 0.10.2 - sha256: 806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b - requires_python: '>=2.6,!=3.0.*,!=3.1.*,!=3.2.*' -- pypi: https://files.pythonhosted.org/packages/c7/2a/f609b420c2f564a748a2d80ebfb2ee02a73ca80223af712fca591386cafb/tornado-6.5.2-cp39-abi3-win_amd64.whl + size: 3526350 + timestamp: 1769460339384 +- pypi: https://files.pythonhosted.org/packages/33/f0/3fe8c6e69135a845f4106f2ff8b6805638d4e85c264e70114e8126689587/tokenize_rt-6.2.0-py2.py3-none-any.whl + name: tokenize-rt + version: 6.2.0 + sha256: a152bf4f249c847a66497a4a95f63376ed68ac6abf092a2f7cfb29d044ecff44 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl + name: tomli + version: 2.4.0 + sha256: d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl + name: tomli + version: 2.4.0 + sha256: 9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl + name: tomli + version: 2.4.0 + sha256: 84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl + name: tomli + version: 2.4.0 + sha256: 3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl + name: tomli + version: 2.4.0 + sha256: b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl + name: tomli + version: 2.4.0 + sha256: 5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: tomli + version: 2.4.0 + sha256: 1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: tomli + version: 2.4.0 + sha256: 5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/50/d4/e51d52047e7eb9a582da59f32125d17c0482d065afd5d3bc435ff2120dc5/tornado-6.5.4-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: tornado - version: 6.5.2 - sha256: e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f + version: 6.5.4 + sha256: e5fb5e04efa54cf0baabdd10061eb4148e0be137166146fff835745f59ab9f7f requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f2/b5/9b575a0ed3e50b00c40b08cbce82eb618229091d09f6d14bce80fc01cb0b/tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/ab/a9/e94a9d5224107d7ce3cc1fab8d5dc97f5ea351ccc6322ee4fb661da94e35/tornado-6.5.4-cp39-abi3-macosx_10_9_universal2.whl name: tornado - version: 6.5.2 - sha256: 583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef + version: 6.5.4 + sha256: d6241c1a16b1c9e4cc28148b1cda97dd1c6cb4fb7068ac1bedc610768dff0ba9 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f6/48/6a7529df2c9cc12efd2e8f5dd219516184d703b34c06786809670df5b3bd/tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl +- pypi: https://files.pythonhosted.org/packages/d6/6d/c69be695a0a64fd37a97db12355a035a6d90f79067a3cf936ec2b1dc38cd/tornado-6.5.4-cp39-abi3-win_amd64.whl name: tornado - version: 6.5.2 - sha256: 2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6 + version: 6.5.4 + sha256: fa07d31e0cd85c60713f2b995da613588aa03e1303d75705dca6af8babc18ddc requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/f9/41/fb15f06e33d7430ca89420283a8762a4e6b8025b800ea51796ab5e6d9559/tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/db/7e/f7b8d8c4453f305a51f80dbb49014257bb7d28ccb4bbb8dd328ea995ecad/tornado-6.5.4-cp39-abi3-macosx_10_9_x86_64.whl name: tornado - version: 6.5.2 - sha256: e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108 + version: 6.5.4 + sha256: 2d50f63dda1d2cac3ae1fa23d254e16b5e38153758470e9956cbc3d813d40843 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/fc/cc/e09c0d663a004945f82beecd4f147053567910479314e8d01ba71e5d5dea/tox-4.32.0-py3-none-any.whl - name: tox - version: 4.32.0 - sha256: 451e81dc02ba8d1ed20efd52ee409641ae4b5d5830e008af10fe8823ef1bd551 - requires_dist: - - cachetools>=6.2 - - chardet>=5.2 - - colorama>=0.4.6 - - filelock>=3.20 - - packaging>=25 - - platformdirs>=4.5 - - pluggy>=1.6 - - pyproject-api>=1.9.1 - - tomli>=2.3 ; python_full_version < '3.11' - - typing-extensions>=4.15 ; python_full_version < '3.11' - - virtualenv>=20.34 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/fd/9e/8d50f3b3fc4af8c73154f64d4a2293bfa2d517a19000e70ef2d614254084/tox_gh_actions-3.5.0-py3-none-any.whl - name: tox-gh-actions - version: 3.5.0 - sha256: 070790114c92f4c94337047515ca5e077ceb269a5cb9366e0a0b3440a024eca1 - requires_dist: - - tox>=4,<5 - - devpi-process ; extra == 'testing' - - mypy ; platform_python_implementation == 'CPython' and extra == 'testing' - - pre-commit ; extra == 'testing' - - pytest>=7 ; extra == 'testing' - - pytest-cov>=4 ; extra == 'testing' - - pytest-mock>=3 ; extra == 'testing' - - pytest-randomly>=3 ; extra == 'testing' - requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl name: traitlets version: 5.14.3 @@ -5502,27 +9910,34 @@ packages: - pytest-mypy-testing ; extra == 'test' - pytest>=7.0,<8.2 ; extra == 'test' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/bb/4a/2e5583e544bc437d5e8e54b47db87430df9031b29b48d17f26d129fa60c0/trove_classifiers-2026.1.14.14-py3-none-any.whl name: trove-classifiers - version: 2025.11.14.15 - sha256: d1dac259c1e908939862e3331177931c6df0a37af2c1a8debcc603d9115fcdd9 + version: 2026.1.14.14 + sha256: 1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d - pypi: https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl name: typing-extensions version: 4.15.0 sha256: f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl + name: typing-inspection + version: 0.4.2 + sha256: 4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7 + requires_dist: + - typing-extensions>=4.12.0 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl name: tzdata - version: '2025.2' - sha256: 1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8 + version: '2025.3' + sha256: 06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 requires_python: '>=2' -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - sha256: 5aaa366385d716557e365f0a4e9c3fca43ba196872abbbe3d56bb610d131e192 - md5: 4222072737ccff51314b5ece9c7d6f5a +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c + md5: ad659d0a2b3e47e38d829aa8cad2d610 license: LicenseRef-Public-Domain purls: [] - size: 122968 - timestamp: 1742727099393 + size: 119135 + timestamp: 1767016325805 - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 md5: 71b24316859acd00bdb8b38f5e2ce328 @@ -5548,6 +9963,10 @@ packages: - python-docs-theme ; extra == 'doc' - uncertainties[arrays,doc,test] ; extra == 'all' requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/f7/46/e7cea8159199096e1df52da20a57a6665da80c37fb8aeb848a3e47442c32/untokenize-0.1.1.tar.gz + name: untokenize + version: 0.1.1 + sha256: 3865dbbbb8efb4bb5eaa72f1be7f3e0be00ea8b7f125c69cbd1f5fda926f37a2 - pypi: https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl name: uri-template version: 1.3.0 @@ -5574,89 +9993,144 @@ packages: - flake8-use-fstring ; extra == 'dev' - pep8-naming ; extra == 'dev' requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl name: urllib3 - version: 2.5.0 - sha256: e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc + version: 2.6.3 + sha256: bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 requires_dist: - - brotli>=1.0.9 ; platform_python_implementation == 'CPython' and extra == 'brotli' - - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'brotli' + - brotli>=1.2.0 ; platform_python_implementation == 'CPython' and extra == 'brotli' + - brotlicffi>=1.2.0.0 ; platform_python_implementation != 'CPython' and extra == 'brotli' - h2>=4,<5 ; extra == 'h2' - pysocks>=1.5.6,!=1.5.7,<2.0 ; extra == 'socks' - - zstandard>=0.18.0 ; extra == 'zstd' + - backports-zstd>=1.0.0 ; python_full_version < '3.14' and extra == 'zstd' requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_32.conda - sha256: 82250af59af9ff3c6a635dd4c4764c631d854feb334d6747d356d949af44d7cf - md5: ef02bbe151253a72b8eda264a935db66 +- pypi: https://files.pythonhosted.org/packages/b7/ee/e9c95cda829131f71a8dff5ce0406059fd16e591c074414e31ada19ba7c3/validate_pyproject-0.25-py3-none-any.whl + name: validate-pyproject + version: '0.25' + sha256: f9d05e2686beff82f9ea954f582306b036ced3d3feb258c1110f2c2a495b1981 + requires_dist: + - fastjsonschema>=2.16.2,<=3 + - packaging>=24.2 ; extra == 'all' + - trove-classifiers>=2021.10.20 ; extra == 'all' + - tomli>=1.2.1 ; python_full_version < '3.11' and extra == 'all' + - validate-pyproject-schema-store ; extra == 'store' + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + sha256: 9dc40c2610a6e6727d635c62cced5ef30b7b30123f5ef67d6139e23d21744b3a + md5: 1e610f2416b6acdd231c5f573d754a0f depends: - - vc14_runtime >=14.42.34433 + - vc14_runtime >=14.44.35208 track_features: - vc14 license: BSD-3-Clause license_family: BSD purls: [] - size: 18861 - timestamp: 1760418772353 -- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda - sha256: e3a3656b70d1202e0d042811ceb743bd0d9f7e00e2acdf824d231b044ef6c0fd - md5: 378d5dcec45eaea8d303da6f00447ac0 + size: 19356 + timestamp: 1767320221521 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + sha256: 02732f953292cce179de9b633e74928037fa3741eb5ef91c3f8bae4f761d32a5 + md5: 37eb311485d2d8b2c419449582046a42 depends: - ucrt >=10.0.20348.0 - - vcomp14 14.44.35208 h818238b_32 + - vcomp14 14.44.35208 h818238b_34 constrains: - - vs2015_runtime 14.44.35208.* *_32 + - vs2015_runtime 14.44.35208.* *_34 license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime license_family: Proprietary purls: [] - size: 682706 - timestamp: 1760418629729 -- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda - sha256: f3790c88fbbdc55874f41de81a4237b1b91eab75e05d0e58661518ff04d2a8a1 - md5: 58f67b437acbf2764317ba273d731f1d + size: 683233 + timestamp: 1767320219644 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + sha256: 878d5d10318b119bd98ed3ed874bd467acbe21996e1d81597a1dbf8030ea0ce6 + md5: 242d9f25d2ae60c76b38a5e42858e51d depends: - ucrt >=10.0.20348.0 constrains: - - vs2015_runtime 14.44.35208.* *_32 + - vs2015_runtime 14.44.35208.* *_34 license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime license_family: Proprietary purls: [] - size: 114846 - timestamp: 1760418593847 -- pypi: https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl + size: 115235 + timestamp: 1767320173250 +- pypi: https://files.pythonhosted.org/packages/1c/59/964ecb8008722d27d8a835baea81f56a91cea8e097b3be992bc6ccde6367/versioningit-3.3.0-py3-none-any.whl + name: versioningit + version: 3.3.0 + sha256: 23b1db3c4756cded9bd6b0ddec6643c261e3d0c471707da3e0b230b81ce53e4b + requires_dist: + - importlib-metadata>=3.6 ; python_full_version < '3.10' + - packaging>=17.1 + - tomli>=1.2,<3.0 ; python_full_version < '3.11' + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/a4/ce/3b6fee91c85626eaf769d617f1be9d2e15c1cca027bbdeb2e0d751469355/verspec-0.1.0-py3-none-any.whl + name: verspec + version: 0.1.0 + sha256: 741877d5633cc9464c45a469ae2a31e801e6dbbaa85b9675d481cda100f11c31 + requires_dist: + - coverage ; extra == 'test' + - flake8>=3.7 ; extra == 'test' + - mypy ; extra == 'test' + - pretend ; extra == 'test' + - pytest ; extra == 'test' +- pypi: https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl name: virtualenv - version: 20.35.4 - sha256: c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b + version: 21.1.0 + sha256: 164f5e14c5587d170cf98e60378eb91ea35bf037be313811905d3a24ea33cc07 requires_dist: - distlib>=0.3.7,<1 - - filelock>=3.12.2,<4 + - filelock>=3.24.2,<4 ; python_full_version >= '3.10' + - filelock>=3.16.1,<=3.19.1 ; python_full_version < '3.10' - importlib-metadata>=6.6 ; python_full_version < '3.8' - platformdirs>=3.9.1,<5 + - python-discovery>=1 - typing-extensions>=4.13.2 ; python_full_version < '3.11' - - furo>=2023.7.26 ; extra == 'docs' - - proselint>=0.13 ; extra == 'docs' - - sphinx>=7.1.2,!=7.3 ; extra == 'docs' - - sphinx-argparse>=0.4 ; extra == 'docs' - - sphinxcontrib-towncrier>=0.2.1a0 ; extra == 'docs' - - towncrier>=23.6 ; extra == 'docs' - - covdefaults>=2.3 ; extra == 'test' - - coverage-enable-subprocess>=1 ; extra == 'test' - - coverage>=7.2.7 ; extra == 'test' - - flaky>=3.7 ; extra == 'test' - - packaging>=23.1 ; extra == 'test' - - pytest-env>=0.8.2 ; extra == 'test' - - pytest-freezer>=0.4.8 ; (python_full_version >= '3.13' and platform_python_implementation == 'CPython' and sys_platform == 'win32' and extra == 'test') or (platform_python_implementation == 'GraalVM' and extra == 'test') or (platform_python_implementation == 'PyPy' and extra == 'test') - - pytest-mock>=3.11.1 ; extra == 'test' - - pytest-randomly>=3.12 ; extra == 'test' - - pytest-timeout>=2.1 ; extra == 'test' - - pytest>=7.4 ; extra == 'test' - - setuptools>=68 ; extra == 'test' - - time-machine>=2.10 ; platform_python_implementation == 'CPython' and extra == 'test' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl + name: watchdog + version: 6.0.0 + sha256: ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2 + requires_dist: + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl + name: watchdog + version: 6.0.0 + sha256: 76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134 + requires_dist: + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl + name: watchdog + version: 6.0.0 + sha256: 20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2 + requires_dist: + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl + name: watchdog + version: 6.0.0 + sha256: afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c + requires_dist: + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl + name: watchdog + version: 6.0.0 + sha256: cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680 + requires_dist: + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl + name: watchdog + version: 6.0.0 + sha256: a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b + requires_dist: + - pyyaml>=3.10 ; extra == 'watchmedo' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl name: wcwidth - version: 0.2.14 - sha256: a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1 - requires_python: '>=3.6' + version: 0.6.0 + sha256: 1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad + requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl name: webcolors version: 25.10.0 @@ -5679,6 +10153,11 @@ packages: - sphinx-rtd-theme>=1.1.0 ; extra == 'docs' - myst-parser>=2.0.0 ; extra == 'docs' requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl + name: widgetsnbextension + version: 4.0.15 + sha256: 8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366 + requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl name: wsproto version: 1.3.2 @@ -5686,39 +10165,132 @@ packages: requires_dist: - h11>=0.16.0,<1 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl name: yarl - version: 1.22.0 - sha256: 01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a + version: 1.23.0 + sha256: cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c requires_dist: - idna>=2.0 - multidict>=4.0 - propcache>=0.2.1 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: yarl - version: 1.22.0 - sha256: bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b + version: 1.23.0 + sha256: 34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 requires_dist: - idna>=2.0 - multidict>=4.0 - propcache>=0.2.1 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl name: yarl - version: 1.22.0 - sha256: 22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c + version: 1.23.0 + sha256: 4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5 requires_dist: - idna>=2.0 - multidict>=4.0 - propcache>=0.2.1 - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl + name: yarl + version: 1.23.0 + sha256: baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3 + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl + name: yarl + version: 1.23.0 + sha256: bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl + name: yarl + version: 1.23.0 + sha256: 99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl + name: yarl + version: 1.23.0 + sha256: 7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b + requires_dist: + - idna>=2.0 + - multidict>=4.0 + - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl name: yarl - version: 1.22.0 - sha256: 47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d + version: 1.23.0 + sha256: dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 requires_dist: - idna>=2.0 - multidict>=4.0 - propcache>=0.2.1 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl + name: zipp + version: 3.23.0 + sha256: 071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e + requires_dist: + - pytest>=6,!=8.1.* ; extra == 'test' + - jaraco-itertools ; extra == 'test' + - jaraco-functools ; extra == 'test' + - more-itertools ; extra == 'test' + - big-o ; extra == 'test' + - pytest-ignore-flaky ; extra == 'test' + - jaraco-test ; extra == 'test' + - sphinx>=3.5 ; extra == 'doc' + - jaraco-packaging>=9.3 ; extra == 'doc' + - rst-linker>=1.9 ; extra == 'doc' + - furo ; extra == 'doc' + - sphinx-lint ; extra == 'doc' + - jaraco-tidelift>=1.4 ; extra == 'doc' + - pytest-checkdocs>=2.4 ; extra == 'check' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' + - pytest-cov ; extra == 'cover' + - pytest-enabler>=2.2 ; extra == 'enabler' + - pytest-mypy ; extra == 'type' requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 + md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 + depends: + - __glibc >=2.17,<3.0.a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 601375 + timestamp: 1764777111296 +- conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + sha256: 47101a4055a70a4876ffc87b750ab2287b67eca793f21c8224be5e1ee6394d3f + md5: 727109b184d680772e3122f40136d5ca + depends: + - __osx >=10.13 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 528148 + timestamp: 1764777156963 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 + md5: ab136e4c34e97f34fb621d2592a393d8 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 433413 + timestamp: 1764777166076 diff --git a/pixi.toml b/pixi.toml index a7a8897b..5bc43ea6 100644 --- a/pixi.toml +++ b/pixi.toml @@ -1,54 +1,259 @@ +####################### +# ENVIRONMENT VARIABLES +####################### + +# Platform-independent + +[activation.env] +PYTHONIOENCODING = "utf-8" + +# Platform-specific + +# Ensures the main package is used from the source code during +# development, even if main package is installed in editable mode +# via uv. This is important because `pixi update` might replace +# the installed version with the latest released version. + +# Unix/macOS +[target.unix.activation.env] +PYTHONPATH = "${PIXI_PROJECT_ROOT}/src${PYTHONPATH:+:${PYTHONPATH}}" + +# Windows +[target.win.activation.env] +PYTHONPATH = "${PIXI_PROJECT_ROOT}/src;%PYTHONPATH%" + +########### +# WORKSPACE +########### + [workspace] -name = "easyscience" -channels = ["conda-forge"] -platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"] + +# Supported platforms for the lock file (pixi.lock) +platforms = ['win-64', 'linux-64', 'osx-64', 'osx-arm64'] + +# Channels for fetching packages +channels = ['conda-forge'] + +########## +# FEATURES +########## + +# Default feature configuration [dependencies] -python = ">=3.11,<3.14" +nodejs = '*' # Required for Prettier (non-Python formatting) +#gsl = '*' # GNU Scientific Library; required for pdffit2 -[feature.dev.pypi-dependencies] -# Development dependencies -easyscience = { path = ".", extras = ["dev"], editable = true } +[pypi-dependencies] # == [feature.default.pypi-dependencies] +#pip = '*' # Native package installer +easyscience = { path = ".", editable = true, extras = ['dev'] } -[feature.docs.pypi-dependencies] -# Documentation dependencies -easyscience = { path = ".", extras = ["docs"], editable = true } +# Specific features: Set specific Python versions -[feature.build.pypi-dependencies] -# build dependencies -easyscience = { path = ".", extras = ["build"], editable = true } +[feature.py-min.dependencies] +python = '3.11.*' +[feature.py-max.dependencies] +python = '3.13.*' + +############## +# ENVIRONMENTS +############## [environments] -# Default environment with basic build setup -default = ["build"] -# Development environment with build, dev, and docs features -dev = ["build", "dev", "docs"] + +# The `default` feature is always included in all environments. +# Additional features can be specified per environment. +py-311-env = { features = ['default', 'py-min'] } +py-313-env = { features = ['default', 'py-max'] } + +# The `default` environment is always created and includes the `default` feature. +# It does not need to be specified explicitly unless non-default features are included. +default = { features = ['default', 'py-max'] } + +####### +# TASKS +####### [tasks] -# Development tasks -test = "pytest --cov=src/easyscience tests --cov-branch --cov-report=xml:coverage-unit.xml" -test-unit = "pytest tests/unit_tests" -test-integration = "pytest tests/integration_tests" -# Code quality tasks -lint-check = "ruff check ." -lint = "ruff check . --fix" -format-check = "ruff format . --check" -format = "ruff format ." +################## +# 🧪 Testing Tasks +################## -# Build tasks -build = "python -m build" -clean = "rm -rf dist/ build/ *.egg-info/" -update-lock = "pixi update" +unit-tests = 'python -m pytest tests/unit/ --color=yes -v' +integration-tests = 'python -m pytest tests/integration/ --color=yes -n auto -v' +notebook-tests = 'python -m pytest --nbmake docs/docs/tutorials/ --nbmake-timeout=600 --color=yes -n auto -v' +script-tests = 'python -m pytest tools/test_scripts.py --color=yes -n auto -v' -# Tox tasks -tox = "tox" +test = { depends-on = ['unit-tests'] } -# Documentation tasks -docs-build = "sphinx-build -b html docs/src docs/_build/html" -docs-clean = "rm -rf docs/_build/" +########### +# ✔️ Checks +########### -[pypi-dependencies] # == [feature.default.pypi-dependencies] -# Editable install of the package itself -easyscience = { path = ".", editable = true } +pyproject-check = 'python -m validate_pyproject pyproject.toml' +docs-format-check = 'docformatter --check src/ docs/docs/tutorials/' +notebook-format-check = 'nbqa ruff docs/docs/tutorials/' +py-lint-check = 'ruff check src/ tests/ docs/docs/tutorials/' +py-format-check = "ruff format --check src/ tests/ docs/docs/tutorials/" +nonpy-format-check = "npx prettier --list-different --config=prettierrc.toml --ignore-unknown ." +nonpy-format-check-modified = "python tools/nonpy_prettier_modified.py" + +check = 'pre-commit run --hook-stage manual --all-files' + +########## +# 🛠️ Fixes +########## + +docs-format-fix = 'docformatter --in-place src/ docs/docs/tutorials/' +notebook-format-fix = 'nbqa ruff --fix docs/docs/tutorials/' +py-lint-fix = 'ruff check --fix src/ tests/ docs/docs/tutorials/' +py-format-fix = "ruff format src/ tests/ docs/docs/tutorials/" +nonpy-format-fix = 'npx prettier --write --list-different --config=prettierrc.toml --ignore-unknown .' +nonpy-format-fix-modified = "python tools/nonpy_prettier_modified.py --write" +success-message-fix = 'echo "✅ All code auto-formatting steps have been applied."' + +fix = { depends-on = [ + 'py-format-fix', + 'docs-format-fix', + 'py-lint-fix', + 'nonpy-format-fix', + 'notebook-format-fix', + 'success-message-fix', +] } + +#################### +# 🧮 Code Complexity +#################### + +complexity-check = 'radon cc -s src/' +complexity-check-json = 'radon cc -s -j src/' +maintainability-check = 'radon mi src/' +maintainability-check-json = 'radon mi -j src/' +raw-metrics = 'radon raw -s src/' +raw-metrics-json = 'radon raw -s -j src/' + +############# +# 📊 Coverage +############# + +unit-tests-coverage = 'pixi run unit-tests --cov=src/easyscience --cov-report=term-missing' +integration-tests-coverage = 'pixi run integration-tests --cov=src/easyscience --cov-report=term-missing' +docstring-coverage = 'interrogate -c pyproject.toml src/easyscience' + +cov = { depends-on = [ + 'docstring-coverage', + 'unit-tests-coverage', + 'integration-tests-coverage', +] } + +######################## +# 📓 Notebook Management +######################## + +notebook-convert = 'jupytext docs/docs/tutorials/*.py --from py:percent --to ipynb' +notebook-strip = 'nbstripout docs/docs/tutorials/*.ipynb' +notebook-tweak = 'python tools/tweak_notebooks.py tutorials/' +notebook-exec = 'python -m pytest --nbmake docs/docs/tutorials/ --nbmake-timeout=600 --overwrite --color=yes -n auto -v' + +notebook-prepare = { depends-on = [ + #'notebook-convert', + 'notebook-strip', + #'notebook-tweak', +] } + +######################## +# 📚 Documentation Tasks +######################## + +docs-vars = "JUPYTER_PLATFORM_DIRS=1 PYTHONWARNINGS='ignore::RuntimeWarning'" +docs-pre = "pixi run docs-vars python -m mkdocs" +docs-serve = "pixi run docs-pre serve -f docs/mkdocs.yml" +docs-serve-dirty = "pixi run docs-serve --dirty" +docs-build = "pixi run docs-pre build -f docs/mkdocs.yml" +docs-build-local = "pixi run docs-build --no-directory-urls" + +docs-deploy-pre = 'mike deploy -F docs/mkdocs.yml --push --branch gh-pages --update-aliases --alias-type redirect' +docs-set-default-pre = 'mike set-default -F docs/mkdocs.yml --push --branch gh-pages' + +docs-update-assets = 'python tools/update_docs_assets.py' + +############################## +# 📦 Template Management Tasks +############################## + +copier-copy = "copier copy gh:easyscience/templates . --data-file .copier-answers.yml --data template_type=lib" +copier-recopy = "copier recopy --data-file .copier-answers.yml --data template_type=lib" +copier-update = "copier update --data-file .copier-answers.yml --data template_type=lib" + +##################### +# 🪝 Pre-commit Hooks +##################### + +pre-commit-clean = 'pre-commit clean' +pre-commit-install = 'pre-commit install --hook-type pre-commit --hook-type pre-push --overwrite' +pre-commit-uninstall = 'pre-commit uninstall --hook-type pre-commit --hook-type pre-push' +pre-commit-setup = { depends-on = [ + 'pre-commit-clean', + 'pre-commit-uninstall', + 'pre-commit-install', +] } + +################# +# 🐙️ GitHub Tasks +################# + +repo-wiki = 'gh api -X PATCH repos/easyscience/core -f has_wiki=false' +repo-discussions = 'gh api -X PATCH repos/easyscience/core -f has_discussions=true' +repo-description = "gh api -X PATCH repos/easyscience/core -f description='Core building blocks for EasyScience'" +repo-homepage = "gh api -X PATCH repos/easyscience/core -f homepage='https://easyscience.github.io/core'" +repo-config = { depends-on = [ + 'repo-wiki', + 'repo-discussions', + 'repo-description', + 'repo-homepage', +] } + +master-protection = 'gh api -X POST repos/easyscience/core/rulesets --input .github/configs/rulesets-master.json' +develop-protection = 'gh api -X POST repos/easyscience/core/rulesets --input .github/configs/rulesets-develop.json' +gh-pages-protection = 'gh api -X POST repos/easyscience/core/rulesets --input .github/configs/rulesets-gh-pages.json' +branch-protection = { depends-on = [ + 'master-protection', + 'develop-protection', + 'gh-pages-protection', +] } + +pages-deployment = 'gh api -X POST repos/easyscience/core/pages --input .github/configs/pages-deployment.json' + +github-labels = 'python tools/update_github_labels.py' + +######################### +# ⚖️ SPDX License Headers +######################### + +spdx-remove = 'python tools/remove_spdx.py src/ tests/' +spdx-add = 'python tools/add_spdx.py src/ tests/' +spdx-check = 'python tools/check_spdx.py src/ tests/' + +#################################### +# 🚀 Other Development & Build Tasks +#################################### + +default-build = 'python -m build' +dist-build = 'python -m build --wheel --outdir dist' + +npm-config = 'npm config set registry https://registry.npmjs.org/' +prettier-install = 'npm install --no-save --no-audit --no-fund prettier prettier-plugin-toml' + +clean-pycache = "find . -type d -name '__pycache__' -prune -exec rm -rf '{}' +" + +post-install = { depends-on = [ + 'npm-config', + 'prettier-install', + #'pre-commit-setup', +] } +########################## +# 🔗 Main Package Shortcut +########################## +easyscience = 'python -m easyscience' diff --git a/prettierrc.toml b/prettierrc.toml new file mode 100644 index 00000000..b98c86eb --- /dev/null +++ b/prettierrc.toml @@ -0,0 +1,22 @@ +plugins = [ + "prettier-plugin-toml", # use the TOML plugin +] + +endOfLine = 'lf' # change line endings to LF +proseWrap = 'always' # change wrapping in Markdown files +semi = false # remove semicolons +singleQuote = true # use single quotes instead of double quotes +tabWidth = 2 # change tab width to 2 spaces +useTabs = false # use spaces instead of tabs + +printWidth = 79 # wrap lines at 79 characters + +[[overrides]] +files = ["*.md"] +[overrides.options] +printWidth = 72 # wrap Markdown files at 72 characters + +[[overrides]] +files = ["*.yml", "*.yaml"] +[overrides.options] +printWidth = 88 # wrap YAML files at 88 characters diff --git a/pyproject.toml b/pyproject.toml index 3cdb977c..c4cba0c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,162 +1,243 @@ -[build-system] -requires = [ - "hatchling<=1.21.0", - "setuptools-git-versioning", -] -build-backend = "hatchling.build" - -[tool.setuptools-git-versioning] -enabled = true +############################### +# Configuration for the project +############################### [project] -name = "easyscience" -dynamic = ["version"] -description = "Generic logic for easyScience libraries" -readme = "README.md" -authors = [{name = "EasyScience contributors"}] -license = { file = "LICENSE" } +name = 'easyscience' +dynamic = ['version'] # Use versioningit to manage the version +description = 'Core building blocks for EasyScience' +authors = [{ name = 'EasyScience contributors' }] +readme = 'README.md' +license = 'BSD-3-Clause' +license-files = ['LICENSE'] classifiers = [ - "License :: OSI Approved :: BSD License", - "Operating System :: OS Independent", - "Topic :: Scientific/Engineering", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Development Status :: 3 - Alpha" + 'Intended Audience :: Science/Research', + 'Topic :: Scientific/Engineering', + 'License :: OSI Approved :: BSD License', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 3 :: Only', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', ] -requires-python = ">=3.11" +requires-python = '>=3.11' dependencies = [ - "asteval", - "bumps", - "DFO-LS", - "lmfit", - "numpy", - "uncertainties", - "scipp" + 'asteval', # Safely evaluate Python expressions from strings + 'lmfit', # Non-linear least squares fitting + 'bumps', # Bayesian uncertainty estimation + 'dfo-ls', # Derivative-free optimization + 'uncertainties', # Propagation of uncertainties in calculations + 'numpy', # Numerical computing + 'scipp<26.1.0', # Handling and analysis of scientific data + 'pooch', # Data downloader + 'matplotlib', # Plotting library + 'jupyterlab', # Jupyter notebooks + 'pixi-kernel', # Pixi Jupyter kernel + 'ipykernel', # Jupyter kernel (required for running notebooks) + 'ipywidgets', # Widgets (needed for interactive matplotlib backends) + 'ipympl', # Matplotlib Jupyter widget backend (%matplotlib widget) + 'IPython', # Interactive Python shell ] [project.optional-dependencies] -build = [ - "hatchling <= 1.21.0", - "setuptools-git-versioning", - "build" -] dev = [ - "build", - "codecov", - "flake8", - "matplotlib", - "pytest", - "pytest-cov", - "ruff", - "tox-gh-actions", - "jupyterlab" -] -docs = [ - "doc8", - "readme-renderer", - "sphinx_autodoc_typehints", - "sphinx_book_theme", - "sphinx_gallery", - "toml" + 'GitPython', # Interact with Git repositories + 'build', # Building the package + 'pre-commit', # Pre-commit hooks + 'jinja2', # Templating + 'nbmake', # Building notebooks + 'nbstripout', # Strip output from notebooks + 'nbqa', # Linting and formatting notebooks + 'pytest', # Testing + 'pytest-cov', # Test coverage + 'pytest-xdist', # Enable parallel testing + 'ruff', # Linting and formatting code + 'radon', # Code complexity and maintainability + 'validate-pyproject[all]', # Validate pyproject.toml + 'versioningit', # Automatic versioning from git tags + 'jupytext', # Jupyter notebook text format support + 'jupyterquiz', # Quizzes in Jupyter notebooks + 'docformatter', # Code formatter for docstrings + 'interrogate', # Check for missing docstrings + 'copier', # Template management + 'mike', # MkDocs: Versioned documentation support + 'mkdocs', # Static site generator + 'mkdocs-material', # Documentation framework on top of MkDocs + 'mkdocs-autorefs', # MkDocs: Auto-references support + 'mkdocs-jupyter', # MkDocs: Jupyter notebook support + 'mkdocs-plugin-inline-svg', # MkDocs: Inline SVG support + 'mkdocs-markdownextradata-plugin', # MkDocs: Markdown extra data support, such as global variables + 'mkdocstrings-python', # MkDocs: Python docstring support + 'pyyaml', # YAML parser + 'spdx-headers', # SPDX license header validation ] [project.urls] -homepage = "https://github.com/EasyScience/EasyScience" -documentation = "https://easyscience.github.io/EasyScience/" +Documentation = 'https://easyscience.github.io/core' +'Release Notes' = 'https://github.com/easyscience/core/releases' +'Source Code' = 'https://github.com/easyscience/core' +'Issue Tracker' = 'https://github.com/easyscience/core/issues' -[tool.hatch.version] -path = "src/easyscience/__version__.py" +############################ +# Build system configuration +############################ -[tool.hatch.metadata] -allow-direct-references = true +# Build system 'hatch' -- Python project manager +# https://hatch.pypa.io/ + +# Versioning system 'versioningit' -- Versioning from git tags +# https://versioningit.readthedocs.io/ -[tool.hatch.build.targets.sdist] -packages = ["src"] +[build-system] +build-backend = 'hatchling.build' +requires = ['hatchling', 'versioningit'] + +############################# +# Configuration for hatchling +############################# [tool.hatch.build.targets.wheel] -packages = ["src/easyscience"] -exclude = ["src/easyscience/legacy"] +packages = ['src/easyscience'] +exclude = ['src/easyscience/legacy'] + +[tool.hatch.metadata] +allow-direct-references = true + +[tool.hatch.version] +source = 'versioningit' # Use versioningit to manage the version + +################################ +# Configuration for versioningit +################################ + +# Versioningit generates versions from git tags, so we don't need to +# either specify them statically in pyproject.toml or save them in the +# source code. Do not use {distance} in the version format, as it +# forces a version bump for every commit, which triggers unnecessary +# pixi.lock update without any changes to the source code. + +[tool.versioningit.format] +distance = '{base_version}+dev{distance}' # example: 1.2.3.post4+dev3 +dirty = '{base_version}+dirty{distance}' # example: 0.5.8+dirty3 +distance-dirty = '{base_version}+devdirty{distance}' # example: 0.5.8+devdirty3 + +# Configure how versioningit detects versions from Git +# - 'match' ensures it only considers tags starting with 'v' +# - 'default-tag' is used as a fallback when no matching tag is found +[tool.versioningit.vcs] +method = 'git' +match = ['v*'] +default-tag = 'v999.0.0' + +################################ +# Configuration for interrogate +################################ + +# 'interrogate' -- Check for missing docstrings +# https://interrogate.readthedocs.io/en/latest/ + +[tool.interrogate] +fail-under = 0 # Minimum docstring coverage percentage to pass +verbose = 1 +#exclude = ['src/**/__init__.py'] + +####################################### +# Configuration for coverage/pytest-cov +####################################### [tool.coverage.run] -source = ["src/easyscience"] +branch = true # Measure branch coverage as well +source = ['src'] # Limit coverage to the source code directory + +[tool.coverage.report] +show_missing = true # Show missing lines +skip_covered = false # Skip files with 100% coverage in the report +fail_under = 0 # Minimum coverage percentage to pass + +########################## +# Configuration for pytest +########################## -[tool.github.info] -organization = 'EasyScience' -repo = "easyscience" +[tool.pytest.ini_options] +addopts = '--import-mode=importlib' +markers = ['fast: mark test as fast (should be run on every push)'] +testpaths = ['tests'] + +######################## +# Configuration for ruff +######################## + +# 'ruff' -- Python linter and code formatter +# https://docs.astral.sh/ruff/rules/ [tool.ruff] -line-length = 127 -exclude = [ - "docs", - "examples_old", - "tests" -] +exclude = ['legacy', 'tests'] +indent-width = 4 +line-length = 99 +preview = true # Enable new rules that are not yet stable, like DOC [tool.ruff.format] -quote-style = "single" - -[tool.ruff.per-file-ignores] -# allow asserts in test files -"*test_*.py" = ["S101"] +docstring-code-format = true # Whether to format code snippets in docstrings +docstring-code-line-length = 72 # Line length for code snippets in docstrings +indent-style = 'space' # PEP 8 recommends using spaces over tabs +line-ending = 'lf' # Line endings will be converted to \n +quote-style = 'single' # But double quotes in docstrings (PEP 8, PEP 257) +# https://docs.astral.sh/ruff/rules/ [tool.ruff.lint] -ignore-init-module-imports = true select = [ - # flake8 settings from existing CI setup - "E9", "F63", "F7", "F82", - # Code should be polished to fulfill all cases below - # https://docs.astral.sh/ruff/rules/ - # pycodestyle - "E", - # Pyflakes - "F", - # pyupgrade -# "UP", - # flake8-bugbear -# "B", - # flake8-simplify -# "SIM", - # isort - "I", - # flake8-bandit - "S", + # 'E', # General PEP 8 style errors + 'E9', # Runtime errors (e.g., syntax errors, undefined names) + # 'F', # Pyflakes-specific checks (e.g., unused variables, imports) + 'F63', # Issues related to invalid escape sequences in strings + 'F7', # Type-related errors (e.g., mismatched argument types, unsupported operations) + 'F82', # Import-related errors (e.g., unresolved imports, reimported modules) + 'I', # Import sorting issues (e.g., unsorted imports) + # 'S', # Security-related issues (e.g., use of insecure functions or libraries) + # 'W', # General PEP 8 warnings (e.g., lines too long, trailing whitespace) ] +[tool.ruff.lint.per-file-ignores] +'tests/**/*.py' = ['S101'] # Allow assert statements in tests + +[tool.ruff.lint.flake8-tidy-imports] +ban-relative-imports = 'all' + [tool.ruff.lint.isort] force-single-line = true -[tool.tox] -legacy_tox_ini = """ -[tox] -isolated_build = True -envlist = py{3.11,3.12,3.13} -[gh-actions] -python = - 3.11: py311 - 3.12: py312 - 3.13: py313 -[gh-actions:env] -PLATFORM = - ubuntu-latest: linux - macos-latest: macos - macos-15-intel: macos-intel - windows-latest: windows -[testenv] -passenv = - CI - GITHUB_ACTIONS - GITHUB_ACTION - GITHUB_REF - GITHUB_REPOSITORY - GITHUB_HEAD_REF - GITHUB_RUN_ID - GITHUB_SHA - COVERAGE_FILE -deps = coverage -commands = - pip install -e '.[dev]' - pytest --cov --cov-report=xml -""" +[tool.ruff.lint.mccabe] +max-complexity = 10 # default is 10 + +[tool.ruff.lint.pycodestyle] +# PEP 8 line length guidance: +# https://peps.python.org/pep-0008/#maximum-line-length +# Use 99 characters as the project-wide maximum for regular code lines. +max-line-length = 99 +# allow longer lines so that parameter declarations such as +# `name (Type | Type | None):` remain on a single line. Splitting these +# lines can prevent tools such as MkDocs and IDEs from correctly +# parsing and rendering parameter documentation. +# The descriptive text itself is wrapped more strictly by +# `docformatter` (see the configuration in [tool.docformatter] below) +# whenever it is treated as normal paragraph text. +# The line length for code snippets in docstrings is also more strict, +# as defined in the [tool.ruff.format] section above. +max-doc-length = 99 + +[tool.ruff.lint.pydocstyle] +convention = 'google' + +################################ +# Configuration for docformatter +################################ + +# 'docformatter' -- Code formatter for docstrings +# https://docformatter.readthedocs.io/en/latest/ + +[tool.docformatter] +recursive = true +wrap-summaries = 72 +wrap-descriptions = 72 +close-quotes-on-newline = true diff --git a/resources/images/ec_logo.svg b/resources/images/ec_logo.svg deleted file mode 100644 index 25ee716f..00000000 --- a/resources/images/ec_logo.svg +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/resources/images/ec_logo_single.svg b/resources/images/ec_logo_single.svg deleted file mode 100644 index d6f33918..00000000 --- a/resources/images/ec_logo_single.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - diff --git a/resources/images/ec_logo_wfont.svg b/resources/images/ec_logo_wfont.svg deleted file mode 100644 index 046d884a..00000000 --- a/resources/images/ec_logo_wfont.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - easycore - - - - - - - - \ No newline at end of file diff --git a/resources/scripts/generate_html.py b/resources/scripts/generate_html.py deleted file mode 100644 index 8f1a4cc6..00000000 --- a/resources/scripts/generate_html.py +++ /dev/null @@ -1,28 +0,0 @@ -import sys - -import requests - -org = 'easyScience' -repo = 'EasyScience' -if len(sys.argv) > 1: - repo = sys.argv[1] - -releases = requests.get(f'https://api.github.com/repos/{org}/{repo}/releases').json() # noqa: S113 - -header = ( - f'\n\n\nLinks for {repo} (alpha)\n\n\n

Links for {repo}

' -) -body = '' -for release in releases: - asset_url = release['assets_url'] - assets = requests.get(asset_url).json() # noqa: S113 - for asset in assets: - if asset['name'].endswith('.whl'): - name = asset['name'][:-4] - url = asset['browser_download_url'] - body += f'{name}
\n' -footer = '\n' - -content = '\n'.join([header, body, footer]) -with open('index.html', 'w') as fid: - fid.write(content) diff --git a/src/easyscience/__init__.py b/src/easyscience/__init__.py index e3d4b084..167e98e0 100644 --- a/src/easyscience/__init__.py +++ b/src/easyscience/__init__.py @@ -1,3 +1,8 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + +from importlib.metadata import version + from .global_object import GlobalObject # Must be executed before any other imports @@ -6,13 +11,14 @@ global_object.stack.enabled = False -from .__version__ import __version__ as __version__ # noqa: E402 from .base_classes import ObjBase # noqa: E402 from .fitting import AvailableMinimizers # noqa: E402 from .fitting import Fitter # noqa: E402 from .variable import DescriptorNumber # noqa: E402 from .variable import Parameter # noqa: E402 +__version__ = version('easyscience') + __all__ = [ __version__, global_object, diff --git a/src/easyscience/__version__.py b/src/easyscience/__version__.py deleted file mode 100644 index 04188a16..00000000 --- a/src/easyscience/__version__.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = '2.2.0' diff --git a/src/easyscience/base_classes/__init__.py b/src/easyscience/base_classes/__init__.py index 878d869e..b5dc0418 100644 --- a/src/easyscience/base_classes/__init__.py +++ b/src/easyscience/base_classes/__init__.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from .based_base import BasedBase from .collection_base import CollectionBase from .easy_list import EasyList diff --git a/src/easyscience/base_classes/based_base.py b/src/easyscience/base_classes/based_base.py index a2427c7f..1e5ac567 100644 --- a/src/easyscience/base_classes/based_base.py +++ b/src/easyscience/base_classes/based_base.py @@ -1,8 +1,8 @@ +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project Set[str]: base_cls = getattr(self, '__old_class__', self.__class__) sign = signature(base_cls.__init__) - names = [param.name for param in sign.parameters.values() if param.kind == param.POSITIONAL_OR_KEYWORD] + names = [ + param.name + for param in sign.parameters.values() + if param.kind == param.POSITIONAL_OR_KEYWORD + ] return set(names[1:]) def __reduce__(self): - """ - Make the class picklable. - Due to the nature of the dynamic class definitions special measures need to be taken. + """Make the class picklable. Due to the nature of the dynamic + class definitions special measures need to be taken. :return: Tuple consisting of how to make the object :rtype: tuple @@ -63,9 +71,11 @@ def unique_name(self) -> str: @unique_name.setter def unique_name(self, new_unique_name: str): - """Set a new unique name for the object. The old name is still kept in the map. + """Set a new unique name for the object. The old name is still + kept in the map. - :param new_unique_name: New unique name for the object""" + :param new_unique_name: New unique name for the object + """ if not isinstance(new_unique_name, str): raise TypeError('Unique name has to be a string.') self._unique_name = new_unique_name @@ -73,8 +83,7 @@ def unique_name(self, new_unique_name: str): @property def name(self) -> str: - """ - Get the common name of the object. + """Get the common name of the object. :return: Common name of the object """ @@ -82,8 +91,7 @@ def name(self) -> str: @name.setter def name(self, new_name: str): - """ - Set a new common name for the object. + """Set a new common name for the object. :param new_name: New name for the object :return: None @@ -92,34 +100,32 @@ def name(self, new_name: str): @property def interface(self) -> InterfaceFactoryTemplate: - """ - Get the current interface of the object - """ + """Get the current interface of the object.""" return self._interface @interface.setter def interface(self, new_interface: InterfaceFactoryTemplate): - """ - Set the current interface to the object and generate bindings if possible. iF.e. - ``` - def __init__(self, bar, interface=None, **kwargs): - super().__init__(self, **kwargs) - self.foo = bar - self.interface = interface # As final step after initialization to set correct bindings. - ``` + """Set the current interface to the object and generate bindings + if possible. + + iF.e. ``` def __init__(self, bar, interface=None, **kwargs): + super().__init__(self, **kwargs) self.foo = bar + self.interface = interface # As final step after initialization + to set correct bindings. ``` """ self._interface = new_interface if new_interface is not None: self.generate_bindings() def generate_bindings(self): - """ - Generate or re-generate bindings to an interface (if exists) + """Generate or re-generate bindings to an interface (if exists) :raises: AttributeError """ if self.interface is None: - raise AttributeError('Interface error for generating bindings. `interface` has to be set.') + raise AttributeError( + 'Interface error for generating bindings. `interface` has to be set.' + ) interfaceable_children = [ key for key in self._global_object.map.get_edges(self) @@ -131,17 +137,16 @@ def generate_bindings(self): self.interface.generate_bindings(self) def switch_interface(self, new_interface_name: str): - """ - Switch or create a new interface. - """ + """Switch or create a new interface.""" if self.interface is None: - raise AttributeError('Interface error for generating bindings. `interface` has to be set.') + raise AttributeError( + 'Interface error for generating bindings. `interface` has to be set.' + ) self.interface.switch(new_interface_name) self.generate_bindings() def get_parameters(self) -> List[Parameter]: - """ - Get all parameter objects as a list. + """Get all parameter objects as a list. :return: List of `Parameter` objects. """ @@ -154,8 +159,7 @@ def get_parameters(self) -> List[Parameter]: return par_list def _get_linkable_attributes(self) -> List[DescriptorBase]: - """ - Get all objects which can be linked against as a list. + """Get all objects which can be linked against as a list. :return: List of `Descriptor`/`Parameter` objects. """ @@ -168,8 +172,8 @@ def _get_linkable_attributes(self) -> List[DescriptorBase]: return item_list def get_fit_parameters(self) -> List[Parameter]: - """ - Get all objects which can be fitted (and are not fixed) as a list. + """Get all objects which can be fitted (and are not fixed) as a + list. :return: List of `Parameter` objects which can be used in fitting. """ @@ -183,10 +187,11 @@ def get_fit_parameters(self) -> List[Parameter]: return fit_list def __dir__(self) -> Iterable[str]: - """ - This creates auto-completion and helps out in iPython notebooks. + """This creates auto-completion and helps out in iPython + notebooks. - :return: list of function and parameter names for auto-completion + :return: list of function and parameter names for auto- + completion """ new_class_objs = list(k for k in dir(self.__class__) if not k.startswith('_')) return sorted(new_class_objs) @@ -198,12 +203,14 @@ def __copy__(self) -> BasedBase: return new_obj def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: - """ - Convert an object into a full dictionary using `SerializerDict`. - This is a shortcut for ```obj.encode(encoder=SerializerDict)``` - - :param skip: List of field names as strings to skip when forming the dictionary - :return: encoded object containing all information to reform an EasyScience object. + """Convert an object into a full dictionary using + `SerializerDict`. This is a shortcut for + ```obj.encode(encoder=SerializerDict)``` + + :param skip: List of field names as strings to skip when forming + the dictionary + :return: encoded object containing all information to reform an + EasyScience object. """ # extend skip to include unique_name by default if skip is None: diff --git a/src/easyscience/base_classes/collection_base.py b/src/easyscience/base_classes/collection_base.py index 0a4e8272..3328abc5 100644 --- a/src/easyscience/base_classes/collection_base.py +++ b/src/easyscience/base_classes/collection_base.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from __future__ import annotations @@ -25,8 +24,9 @@ class CollectionBase(BasedBase, MutableSequence): - """ - This is the base class for which all higher level classes are built off of. + """This is the base class for which all higher level classes are + built off of. + NOTE: This object is serializable only if parameters are supplied as: `ObjBase(a=value, b=value)`. For `Parameter` or `Descriptor` objects we can cheat with `ObjBase(*[Descriptor(...), Parameter(...), ...])`. @@ -40,8 +40,7 @@ def __init__( unique_name: Optional[str] = None, **kwargs, ): - """ - Set up the base collection class. + """Set up the base collection class. :param name: Name of this object :type name: str @@ -80,7 +79,9 @@ def __init__( for key in kwargs.keys(): if key in self.__dict__.keys() or key in self.__slots__: - raise AttributeError(f'Given kwarg: `{key}`, is an internal attribute. Please rename.') + raise AttributeError( + f'Given kwarg: `{key}`, is an internal attribute. Please rename.' + ) if kwargs[key]: # Might be None (empty tuple or list) self._global_object.map.add_edge(self, kwargs[key]) self._global_object.map.reset_type(kwargs[key], 'created_internal') @@ -92,8 +93,7 @@ def __init__( self._kwargs._stack_enabled = True def insert(self, index: int, value: Union[DescriptorBase, BasedBase, NewBase]) -> None: - """ - Insert an object into the collection at an index. + """Insert an object into the collection at an index. :param index: Index for EasyScience object to be inserted. :type index: int @@ -119,8 +119,7 @@ def insert(self, index: int, value: Union[DescriptorBase, BasedBase, NewBase]) - raise AttributeError('Only EasyScience objects can be put into an EasyScience group') def __getitem__(self, idx: Union[int, slice]) -> Union[DescriptorBase, BasedBase, NewBase]: - """ - Get an item in the collection based on its index. + """Get an item in the collection based on its index. :param idx: index or slice of the collection. :type idx: Union[int, slice] @@ -129,7 +128,9 @@ def __getitem__(self, idx: Union[int, slice]) -> Union[DescriptorBase, BasedBase """ if isinstance(idx, slice): start, stop, step = idx.indices(len(self)) - return self.__class__(getattr(self, 'name'), *[self[i] for i in range(start, stop, step)]) + return self.__class__( + getattr(self, 'name'), *[self[i] for i in range(start, stop, step)] + ) if str(idx) in self._kwargs.keys(): return self._kwargs[str(idx)] if isinstance(idx, str): @@ -153,8 +154,7 @@ def __getitem__(self, idx: Union[int, slice]) -> Union[DescriptorBase, BasedBase return self._kwargs[keys[idx]] def __setitem__(self, key: int, value: Union[BasedBase, DescriptorBase, NewBase]) -> None: - """ - Set an item via it's index. + """Set an item via it's index. :param key: Index in self. :type key: int @@ -178,11 +178,12 @@ def __setitem__(self, key: int, value: Union[BasedBase, DescriptorBase, NewBase] # REMOVE EDGE self._global_object.map.prune_vertex_from_edge(self, old_item) else: - raise NotImplementedError('At the moment only numerical values or EasyScience objects can be set.') + raise NotImplementedError( + 'At the moment only numerical values or EasyScience objects can be set.' + ) def __delitem__(self, key: int) -> None: - """ - Try to delete an idem by key. + """Try to delete an idem by key. :param key: :type key: @@ -195,8 +196,7 @@ def __delitem__(self, key: int) -> None: del self._kwargs[keys[key]] def __len__(self) -> int: - """ - Get the number of items in this collection + """Get the number of items in this collection. :return: Number of items in this collection. :rtype: int @@ -204,8 +204,7 @@ def __len__(self) -> int: return len(self._kwargs.keys()) def _convert_to_dict(self, in_dict, encoder, skip: List[str] = [], **kwargs) -> dict: - """ - Convert ones self into a serialized form. + """Convert ones self into a serialized form. :return: dictionary of ones self :rtype: dict @@ -220,14 +219,14 @@ def _convert_to_dict(self, in_dict, encoder, skip: List[str] = [], **kwargs) -> @property def data(self) -> Tuple: - """ - The data function returns a tuple of the keyword arguments passed to the - constructor. This is useful for when you need to pass in a dictionary of data - to other functions, such as with matplotlib's plot function. + """The data function returns a tuple of the keyword arguments + passed to the constructor. This is useful for when you need to + pass in a dictionary of data to other functions, such as with + matplotlib's plot function. :param self: Access attributes of the class within the method - :return: The values of the attributes in a tuple - :doc-author: Trelent + :return: The values of the attributes in a tuple :doc-author: + Trelent """ return tuple(self._kwargs.values()) @@ -239,10 +238,10 @@ def sort( mapping: Callable[[Union[BasedBase, DescriptorBase, NewBase]], Any], reverse: bool = False, ) -> None: - """ - Sort the collection according to the given mapping. + """Sort the collection according to the given mapping. - :param mapping: mapping function to sort the collection. i.e. lambda parameter: parameter.value + :param mapping: mapping function to sort the collection. i.e. + lambda parameter: parameter.value :type mapping: Callable :param reverse: Reverse the sorting. :type reverse: bool diff --git a/src/easyscience/base_classes/easy_list.py b/src/easyscience/base_classes/easy_list.py index 6af761e6..39f04eaa 100644 --- a/src/easyscience/base_classes/easy_list.py +++ b/src/easyscience/base_classes/easy_list.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from __future__ import annotations @@ -35,11 +34,12 @@ def __init__( display_name: Optional[str] = None, **kwargs: Any, ): - """ - Initialize the EasyList. + """Initialize the EasyList. + :param args: Initial items to add to the list - :param protected_types: Types that are allowed in the list. Can be a single NewBase subclass or a list of them. - If None, defaults to [NewBase]. + :param protected_types: Types that are allowed in the list. Can + be a single NewBase subclass or a list of them. If None, + defaults to [NewBase]. :param unique_name: Optional unique name for the list :param display_name: Optional display name for the list """ @@ -48,10 +48,14 @@ def __init__( self._protected_types = [NewBase] elif isinstance(protected_types, type) and issubclass(protected_types, NewBase): self._protected_types = [protected_types] - elif isinstance(protected_types, Iterable) and all(issubclass(t, NewBase) for t in protected_types): + elif isinstance(protected_types, Iterable) and all( + issubclass(t, NewBase) for t in protected_types + ): self._protected_types = list(protected_types) else: - raise TypeError('protected_types must be a NewBase subclass or an iterable of NewBase subclasses') + raise TypeError( + 'protected_types must be a NewBase subclass or an iterable of NewBase subclasses' + ) self._data: List[ProtectedType_] = [] # Add initial items @@ -78,8 +82,7 @@ def __getitem__(self, idx: slice) -> 'EasyList[ProtectedType_]': ... @overload def __getitem__(self, idx: str) -> ProtectedType_: ... def __getitem__(self, idx: int | slice | str) -> ProtectedType_ | 'EasyList[ProtectedType_]': - """ - Get an item by index, slice, or unique_name. + """Get an item by index, slice, or unique_name. :param idx: Index, slice, or unique_name of the item :return: The item or a new EasyList for slices @@ -101,9 +104,10 @@ def __setitem__(self, idx: int, value: ProtectedType_) -> None: ... @overload def __setitem__(self, idx: slice, value: Iterable[ProtectedType_]) -> None: ... - def __setitem__(self, idx: int | slice, value: ProtectedType_ | Iterable[ProtectedType_]) -> None: - """ - Set an item at an index. + def __setitem__( + self, idx: int | slice, value: ProtectedType_ | Iterable[ProtectedType_] + ) -> None: + """Set an item at an index. :param idx: Index to set :param value: New value @@ -112,7 +116,9 @@ def __setitem__(self, idx: int | slice, value: ProtectedType_ | Iterable[Protect if not isinstance(value, tuple(self._protected_types)): raise TypeError(f'Items must be one of {self._protected_types}, got {type(value)}') if value is not self._data[idx] and value in self: - warnings.warn(f'Item with unique name "{self._get_key(value)}" already in EasyList, it will be ignored') + warnings.warn( + f'Item with unique name "{self._get_key(value)}" already in EasyList, it will be ignored' + ) return self._data[idx] = value elif isinstance(idx, slice): @@ -121,20 +127,25 @@ def __setitem__(self, idx: int | slice, value: ProtectedType_ | Iterable[Protect replaced = self._data[idx] new_values = list(value) if len(new_values) != len(replaced): - raise ValueError('Length of new values must match the length of the slice being replaced') + raise ValueError( + 'Length of new values must match the length of the slice being replaced' + ) for i, v in enumerate(new_values): if not isinstance(v, tuple(self._protected_types)): raise TypeError(f'Items must be one of {self._protected_types}, got {type(v)}') if v in self and replaced[i] is not v: - warnings.warn(f'Item with unique name "{v.unique_name}" already in EasyList, it will be ignored') - new_values[i] = replaced[i] # Keep the original value if the new one is a duplicate + warnings.warn( + f'Item with unique name "{v.unique_name}" already in EasyList, it will be ignored' + ) + new_values[i] = replaced[ + i + ] # Keep the original value if the new one is a duplicate self._data[idx] = new_values else: raise TypeError('Index must be an int or slice') def __delitem__(self, idx: int | slice | str) -> None: - """ - Delete an item by index, slice, or name. + """Delete an item by index, slice, or name. :param idx: Index, slice, or name of item to delete """ @@ -154,8 +165,7 @@ def __len__(self) -> int: return len(self._data) def insert(self, index: int, value: ProtectedType_) -> None: - """ - Insert an item at an index. + """Insert an item at an index. :param index: Index to insert at :param value: Item to insert @@ -165,13 +175,15 @@ def insert(self, index: int, value: ProtectedType_) -> None: elif not isinstance(value, tuple(self._protected_types)): raise TypeError(f'Items must be one of {self._protected_types}, got {type(value)}') if value in self: - warnings.warn(f'Item with unique name "{self._get_key(value)}" already in EasyList, it will be ignored') + warnings.warn( + f'Item with unique name "{self._get_key(value)}" already in EasyList, it will be ignored' + ) return self._data.insert(index, value) def _get_key(self, obj) -> str: - """ - Get the unique name of an object. + """Get the unique name of an object. + Can be overridden to use a different attribute as the key. :param object: Object to get the key for :return: The key of the object @@ -182,7 +194,9 @@ def _get_key(self, obj) -> str: # Overwriting methods def __repr__(self) -> str: - return f'{self.__class__.__name__} of length {len(self)} of type(s) {self._protected_types}' + return ( + f'{self.__class__.__name__} of length {len(self)} of type(s) {self._protected_types}' + ) def __contains__(self, item: ProtectedType_ | str) -> bool: if isinstance(item, str): @@ -193,8 +207,7 @@ def __reversed__(self): return self._data.__reversed__() def sort(self, key: Callable[[ProtectedType_], Any] = None, reverse: bool = False) -> None: - """ - Sort the collection according to the given key function. + """Sort the collection according to the given key function. :param key: Mapping function to sort by :param reverse: Whether to reverse the sort @@ -212,8 +225,7 @@ def index(self, value: ProtectedType_ | str, start: int = 0, stop: int = None) - return self._data.index(value, start, stop) def pop(self, index: int | str = -1) -> ProtectedType_: - """ - Remove and return an item at the given index or unique_name. + """Remove and return an item at the given index or unique_name. :param index: Index or unique_name of the item to remove :return: The removed item @@ -231,29 +243,31 @@ def pop(self, index: int | str = -1) -> ProtectedType_: # Serialization support def to_dict(self) -> dict: - """ - Convert the EasyList to a dictionary for serialization. + """Convert the EasyList to a dictionary for serialization. :return: Dictionary representation of the EasyList """ dict_repr = super().to_dict() if self._protected_types != [NewBase]: dict_repr['protected_types'] = [ - {'@module': cls_.__module__, '@class': cls_.__name__} for cls_ in self._protected_types + {'@module': cls_.__module__, '@class': cls_.__name__} + for cls_ in self._protected_types ] # noqa: E501 dict_repr['data'] = [item.to_dict() for item in self._data] return dict_repr @classmethod def from_dict(cls, obj_dict: Dict[str, Any]) -> NewBase: - """ - Re-create an EasyScience object from a full encoded dictionary. + """Re-create an EasyScience object from a full encoded + dictionary. :param obj_dict: dictionary containing the serialized contents (from `SerializerDict`) of an EasyScience object :return: Reformed EasyScience object """ if not SerializerBase._is_serialized_easyscience_object(obj_dict): - raise ValueError('Input must be a dictionary representing an EasyScience EasyList object.') + raise ValueError( + 'Input must be a dictionary representing an EasyScience EasyList object.' + ) temp_dict = copy.deepcopy(obj_dict) # Make a copy to avoid mutating the input if temp_dict['@class'] == cls.__name__: if 'protected_types' in temp_dict: @@ -267,7 +281,9 @@ def from_dict(cls, obj_dict: Dict[str, Any]) -> NewBase: cls_ = getattr(mod, classname) protected_types[i] = cls_ else: - raise ImportError(f'Could not import class {classname} from module {modname}') + raise ImportError( + f'Could not import class {classname} from module {modname}' + ) else: raise ValueError( 'Each protected type must be a serialized EasyScience class with @module and @class keys' @@ -278,4 +294,6 @@ def from_dict(cls, obj_dict: Dict[str, Any]) -> NewBase: data = kwargs.pop('data', []) return cls(data, protected_types=protected_types, **kwargs) else: - raise ValueError(f'Class name in dictionary does not match the expected class: {cls.__name__}.') + raise ValueError( + f'Class name in dictionary does not match the expected class: {cls.__name__}.' + ) diff --git a/src/easyscience/base_classes/model_base.py b/src/easyscience/base_classes/model_base.py index 3a6a4061..419492c9 100644 --- a/src/easyscience/base_classes/model_base.py +++ b/src/easyscience/base_classes/model_base.py @@ -1,8 +1,8 @@ +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project Parameter: return self._my_param + @my_param.setter def my_param(self, new_value: float) -> None: self._my_param.value = new_value @@ -43,8 +44,7 @@ def __init__(self, unique_name: Optional[str] = None, display_name: Optional[str super().__init__(unique_name=unique_name, display_name=display_name) def get_all_variables(self) -> List[DescriptorBase]: - """ - Get all `Descriptor` and `Parameter` objects as a list. + """Get all `Descriptor` and `Parameter` objects as a list. :return: List of `Descriptor` and `Parameter` objects. """ @@ -58,40 +58,39 @@ def get_all_variables(self) -> List[DescriptorBase]: return vars def get_all_parameters(self) -> List[Parameter]: - """ - Get all `Parameter` objects as a list. + """Get all `Parameter` objects as a list. :return: List of `Parameter` objects. """ return [param for param in self.get_all_variables() if isinstance(param, Parameter)] def get_fittable_parameters(self) -> List[Parameter]: - """ - Get all parameters which can be fitted as a list. + """Get all parameters which can be fitted as a list. :return: List of `Parameter` objects. """ return [param for param in self.get_all_parameters() if param.independent] def get_free_parameters(self) -> List[Parameter]: - """ - Get all parameters which are currently free to be fitted as a list. + """Get all parameters which are currently free to be fitted as a + list. :return: List of `Parameter` objects. """ return [param for param in self.get_fittable_parameters() if not param.fixed] def get_fit_parameters(self) -> List[Parameter]: - """ - This is an alias for `get_free_parameters`. - To be removed when fully moved to new base classes and minimizer can be changed. + """This is an alias for `get_free_parameters`. + + To be removed when fully moved to new base classes and minimizer + can be changed. """ return self.get_free_parameters() @classmethod def from_dict(cls, obj_dict: Dict[str, Any]) -> ModelBase: - """ - Re-create an EasyScience object with DescriptorNumber attributes from a full encoded dictionary. + """Re-create an EasyScience object with DescriptorNumber + attributes from a full encoded dictionary. :param obj_dict: dictionary containing the serialized contents (from `SerializerDict`) of an EasyScience object :return: Reformed EasyScience object @@ -116,4 +115,6 @@ def from_dict(cls, obj_dict: Dict[str, Any]) -> ModelBase: This should be fixed in the class definition. Error: {e}""") from e return cls_instance else: - raise ValueError(f'Class name in dictionary does not match the expected class: {cls.__name__}.') + raise ValueError( + f'Class name in dictionary does not match the expected class: {cls.__name__}.' + ) diff --git a/src/easyscience/base_classes/new_base.py b/src/easyscience/base_classes/new_base.py index 604233bd..778e9ba9 100644 --- a/src/easyscience/base_classes/new_base.py +++ b/src/easyscience/base_classes/new_base.py @@ -1,8 +1,8 @@ +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project Set[str]: - """ - This method is used by the serializer to determine which arguments are needed - by the constructor to deserialize the object. + """This method is used by the serializer to determine which + arguments are needed by the constructor to deserialize the + object. """ sign = signature(self.__class__.__init__) - names = [param.name for param in sign.parameters.values() if param.kind == param.POSITIONAL_OR_KEYWORD] + names = [ + param.name + for param in sign.parameters.values() + if param.kind == param.POSITIONAL_OR_KEYWORD + ] return set(names[1:]) @property @@ -58,9 +63,11 @@ def unique_name(self) -> str: @unique_name.setter def unique_name(self, new_unique_name: str): - """Set a new unique name for the object. The old name is still kept in the map. + """Set a new unique name for the object. The old name is still + kept in the map. - :param new_unique_name: New unique name for the object""" + :param new_unique_name: New unique name for the object + """ if not isinstance(new_unique_name, str): raise TypeError('Unique name has to be a string.') self._unique_name = new_unique_name @@ -69,8 +76,7 @@ def unique_name(self, new_unique_name: str): @property def display_name(self) -> str: - """ - Get a pretty display name. + """Get a pretty display name. :return: The pretty display name. """ @@ -82,8 +88,7 @@ def display_name(self) -> str: @display_name.setter @property_stack def display_name(self, name: str | None) -> None: - """ - Set the pretty display name. + """Set the pretty display name. :param name: Pretty display name of the object. """ @@ -92,11 +97,13 @@ def display_name(self, name: str | None) -> None: self._display_name = name def to_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: - """ - Convert an EasyScience object into a full dictionary using `SerializerBase`s generic `convert_to_dict` method. + """Convert an EasyScience object into a full dictionary using + `SerializerBase`s generic `convert_to_dict` method. - :param skip: List of field names as strings to skip when forming the dictionary - :return: encoded object containing all information to reform an EasyScience object. + :param skip: List of field names as strings to skip when forming + the dictionary + :return: encoded object containing all information to reform an + EasyScience object. """ serializer = SerializerBase() if skip is None: @@ -109,8 +116,8 @@ def to_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: @classmethod def from_dict(cls, obj_dict: Dict[str, Any]) -> NewBase: - """ - Re-create an EasyScience object from a full encoded dictionary. + """Re-create an EasyScience object from a full encoded + dictionary. :param obj_dict: dictionary containing the serialized contents (from `SerializerDict`) of an EasyScience object :return: Reformed EasyScience object @@ -121,13 +128,16 @@ def from_dict(cls, obj_dict: Dict[str, Any]) -> NewBase: kwargs = SerializerBase.deserialize_dict(obj_dict) return cls(**kwargs) else: - raise ValueError(f'Class name in dictionary does not match the expected class: {cls.__name__}.') + raise ValueError( + f'Class name in dictionary does not match the expected class: {cls.__name__}.' + ) def __dir__(self) -> Iterable[str]: - """ - This creates auto-completion and helps out in iPython notebooks. + """This creates auto-completion and helps out in iPython + notebooks. - :return: list of function and parameter names for auto-completion + :return: list of function and parameter names for auto- + completion """ new_class_objs = list(k for k in dir(self.__class__) if not k.startswith('_')) return sorted(new_class_objs) diff --git a/src/easyscience/base_classes/obj_base.py b/src/easyscience/base_classes/obj_base.py index b42991f8..8576b67b 100644 --- a/src/easyscience/base_classes/obj_base.py +++ b/src/easyscience/base_classes/obj_base.py @@ -1,8 +1,8 @@ +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project None: - """ - Dynamically add a component to the class. This is an internal method, though can be called remotely. - The recommended alternative is to use typing, i.e. + """Dynamically add a component to the class. This is an internal + method, though can be called remotely. The recommended + alternative is to use typing, i.e. .. code-block:: python class Foo(Bar): def __init__(self, foo: Parameter, bar: Parameter): super(Foo, self).__init__(bar=bar) - self._add_component("foo", foo) + self._add_component('foo', foo) :param key: Name of component to be added :param component: Component to be added @@ -133,7 +133,9 @@ def getter(obj: SerializerComponent) -> SerializerComponent: @staticmethod def __setter(key: str) -> Callable[[SerializerComponent], None]: def setter(obj: SerializerComponent, value: float) -> None: - if issubclass(obj._kwargs[key].__class__, (DescriptorBase)) and not issubclass(value.__class__, (DescriptorBase)): + if issubclass(obj._kwargs[key].__class__, (DescriptorBase)) and not issubclass( + value.__class__, (DescriptorBase) + ): obj._kwargs[key].value = value else: obj._kwargs[key] = value diff --git a/src/easyscience/fitting/__init__.py b/src/easyscience/fitting/__init__.py index f34b8b81..54bad74a 100644 --- a/src/easyscience/fitting/__init__.py +++ b/src/easyscience/fitting/__init__.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from .available_minimizers import AvailableMinimizers from .fitter import Fitter from .minimizers.utils import FitResults diff --git a/src/easyscience/fitting/available_minimizers.py b/src/easyscience/fitting/available_minimizers.py index 2d1fb717..0cfd262b 100644 --- a/src/easyscience/fitting/available_minimizers.py +++ b/src/easyscience/fitting/available_minimizers.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import warnings from dataclasses import dataclass from enum import Enum @@ -13,7 +16,11 @@ lmfit_engine_available = True except ImportError: # TODO make this a proper message (use logging?) - warnings.warn('LMFit minimization is not available. Probably lmfit has not been installed.', ImportWarning, stacklevel=2) + warnings.warn( + 'LMFit minimization is not available. Probably lmfit has not been installed.', + ImportWarning, + stacklevel=2, + ) bumps_engine_available = False try: @@ -22,7 +29,11 @@ bumps_engine_available = True except ImportError: # TODO make this a proper message (use logging?) - warnings.warn('Bumps minimization is not available. Probably bumps has not been installed.', ImportWarning, stacklevel=2) + warnings.warn( + 'Bumps minimization is not available. Probably bumps has not been installed.', + ImportWarning, + stacklevel=2, + ) dfo_engine_available = False try: @@ -31,7 +42,11 @@ dfo_engine_available = True except ImportError: # TODO make this a proper message (use logging?) - warnings.warn('DFO minimization is not available. Probably dfols has not been installed.', ImportWarning, stacklevel=2) + warnings.warn( + 'DFO minimization is not available. Probably dfols has not been installed.', + ImportWarning, + stacklevel=2, + ) @dataclass diff --git a/src/easyscience/fitting/calculators/__init__.py b/src/easyscience/fitting/calculators/__init__.py index a3ca5d43..4104ddae 100644 --- a/src/easyscience/fitting/calculators/__init__.py +++ b/src/easyscience/fitting/calculators/__init__.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from .interface_factory import InterfaceFactoryTemplate diff --git a/src/easyscience/fitting/calculators/interface_factory.py b/src/easyscience/fitting/calculators/interface_factory.py index ca4713fd..f9103523 100644 --- a/src/easyscience/fitting/calculators/interface_factory.py +++ b/src/easyscience/fitting/calculators/interface_factory.py @@ -1,8 +1,8 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project List[str]: - """ - Return all available interfaces. + """Return all available interfaces. :return: List of available interface names :rtype: List[str] @@ -95,8 +96,7 @@ def available_interfaces(self) -> List[str]: @property def current_interface(self) -> ABCMeta: - """ - Returns the constructor for the currently selected interface. + """Returns the constructor for the currently selected interface. :return: Interface constructor :rtype: InterfaceTemplate @@ -105,8 +105,8 @@ def current_interface(self) -> ABCMeta: @property def current_interface_name(self) -> str: - """ - Returns the constructor name for the currently selected interface. + """Returns the constructor name for the currently selected + interface. :return: Interface constructor name :rtype: str @@ -117,8 +117,7 @@ def current_interface_name(self) -> str: def fit_func( self, ) -> Callable: # , x_array: np.ndarray, *args, **kwargs) -> np.ndarray: - """ - Pass through to the underlying interfaces fitting function. + """Pass through to the underlying interfaces fitting function. :param x_array: points to be calculated at :type x_array: np.ndarray @@ -128,7 +127,8 @@ def fit_func( :type kwargs: Any :return: points calculated at positional values `x` :rtype: np.ndarray - #""" + # + """ def __fit_func(*args, **kwargs): return self.__interface_obj.fit_func(*args, **kwargs) @@ -139,8 +139,9 @@ def call(self, *args, **kwargs): return self.fit_func(*args, **kwargs) def generate_bindings(self, model, *args, ifun=None, **kwargs): - """ - Automatically bind a `Parameter` to the corresponding interface. + """Automatically bind a `Parameter` to the corresponding + interface. + :param name: parameter name :type name: str :return: binding property @@ -189,9 +190,7 @@ def __state_restore__(cls, interface_str): @staticmethod def return_name(this_interface) -> str: - """ - Return an interfaces name - """ + """Return an interfaces name.""" interface_name = this_interface.__name__ if hasattr(this_interface, 'name'): interface_name = getattr(this_interface, 'name') diff --git a/src/easyscience/fitting/fitter.py b/src/easyscience/fitting/fitter.py index 1ccacbe1..70524996 100644 --- a/src/easyscience/fitting/fitter.py +++ b/src/easyscience/fitting/fitter.py @@ -1,6 +1,6 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause + import functools from typing import Callable from typing import List @@ -19,8 +19,8 @@ class Fitter: - """ - Fitter is a class which makes it possible to undertake fitting utilizing one of the supported minimizers. + """Fitter is a class which makes it possible to undertake fitting + utilizing one of the supported minimizers. """ def __init__(self, fit_object, fit_function: Callable): @@ -45,8 +45,7 @@ def convert_to_pars_obj(self, pars) -> object: # TODO: remove this method when we are ready to adjust the dependent products def initialize(self, fit_object, fit_function: Callable) -> None: - """ - Set the model and callable in the calculator interface. + """Set the model and callable in the calculator interface. :param fit_object: The EasyScience model object :param fit_function: The function to be optimized against. @@ -57,9 +56,10 @@ def initialize(self, fit_object, fit_function: Callable) -> None: # TODO: remove this method when we are ready to adjust the dependent products def create(self, minimizer_enum: Union[AvailableMinimizers, str] = DEFAULT_MINIMIZER) -> None: - """ - Create the required minimizer. - :param minimizer_enum: The enum of the minimization engine to create. + """Create the required minimizer. + + :param minimizer_enum: The enum of the minimization engine to + create. """ if isinstance(minimizer_enum, str): print(f'minimizer should be set with enum {minimizer_enum}') @@ -67,10 +67,10 @@ def create(self, minimizer_enum: Union[AvailableMinimizers, str] = DEFAULT_MINIM self._update_minimizer(minimizer_enum) def switch_minimizer(self, minimizer_enum: Union[AvailableMinimizers, str]) -> None: - """ - Switch minimizer and initialize. + """Switch minimizer and initialize. - :param minimizer_enum: The enum of the minimizer to create and instantiate. + :param minimizer_enum: The enum of the minimizer to create and + instantiate. """ if isinstance(minimizer_enum, str): print(f'minimizer should be set with enum {minimizer_enum}') @@ -79,13 +79,16 @@ def switch_minimizer(self, minimizer_enum: Union[AvailableMinimizers, str]) -> N self._update_minimizer(minimizer_enum) def _update_minimizer(self, minimizer_enum: AvailableMinimizers) -> None: - self._minimizer = factory(minimizer_enum=minimizer_enum, fit_object=self._fit_object, fit_function=self.fit_function) + self._minimizer = factory( + minimizer_enum=minimizer_enum, + fit_object=self._fit_object, + fit_function=self.fit_function, + ) self._enum_current_minimizer = minimizer_enum @property def available_minimizers(self) -> List[str]: - """ - Get a list of the names of available fitting minimizers + """Get a list of the names of available fitting minimizers. :return: List of available fitting minimizers :rtype: List[str] @@ -94,8 +97,7 @@ def available_minimizers(self) -> List[str]: @property def minimizer(self) -> MinimizerBase: - """ - Get the current fitting minimizer object. + """Get the current fitting minimizer object. :return: :rtype: MinimizerBase @@ -104,8 +106,7 @@ def minimizer(self) -> MinimizerBase: @property def tolerance(self) -> float: - """ - Get the tolerance for the minimizer. + """Get the tolerance for the minimizer. :return: Tolerance for the minimizer """ @@ -113,8 +114,7 @@ def tolerance(self) -> float: @tolerance.setter def tolerance(self, tolerance: float) -> None: - """ - Set the tolerance for the minimizer. + """Set the tolerance for the minimizer. :param tolerance: Tolerance for the minimizer """ @@ -122,8 +122,7 @@ def tolerance(self, tolerance: float) -> None: @property def max_evaluations(self) -> int: - """ - Get the maximal number of evaluations for the minimizer. + """Get the maximal number of evaluations for the minimizer. :return: Maximal number of steps for the minimizer """ @@ -131,25 +130,24 @@ def max_evaluations(self) -> int: @max_evaluations.setter def max_evaluations(self, max_evaluations: int) -> None: - """ - Set the maximal number of evaluations for the minimizer. + """Set the maximal number of evaluations for the minimizer. - :param max_evaluations: Maximal number of steps for the minimizer + :param max_evaluations: Maximal number of steps for the + minimizer """ self._max_evaluations = max_evaluations @property def fit_function(self) -> Callable: - """ - The raw fit function that the optimizer will call (no wrapping) - :return: Raw fit function + """The raw fit function that the optimizer will call (no + wrapping) :return: Raw fit function. """ return self._fit_function @fit_function.setter def fit_function(self, fit_function: Callable) -> None: - """ - Set the raw fit function to a new one. + """Set the raw fit function to a new one. + :param fit_function: New fit function :return: None """ @@ -158,26 +156,25 @@ def fit_function(self, fit_function: Callable) -> None: @property def fit_object(self): - """ - The EasyScience object which will be used as a model - :return: EasyScience Model + """The EasyScience object which will be used as a model :return: + + EasyScience Model. """ return self._fit_object @fit_object.setter def fit_object(self, fit_object) -> None: - """ - Set the EasyScience object which wil be used as a model - :param fit_object: New EasyScience object - :return: None + """Set the EasyScience object which wil be used as a model + :param fit_object: New EasyScience object :return: None. """ self._fit_object = fit_object self._update_minimizer(self._enum_current_minimizer) def _fit_function_wrapper(self, real_x=None, flatten: bool = True) -> Callable: - """ - Simple fit function which injects the real X (independent) values into the - optimizer function. This will also flatten the results if needed. + """Simple fit function which injects the real X (independent) + values into the optimizer function. + + This will also flatten the results if needed. :param real_x: Independent x parameters to be injected :param flatten: Should the result be a flat 1D array? :return: Wrapped optimizer function. @@ -197,10 +194,13 @@ def wrapped_fit_function(x, **kwargs): @property def fit(self) -> Callable: - """ - Property which wraps the current `fit` function from the fitting interface. This property return a wrapped fit - function which converts the input data into the correct shape for the optimizer, wraps the fit function to - re-constitute the independent variables and once the fit is completed, reshape the inputs to those expected. + """Property which wraps the current `fit` function from the + fitting interface. + + This property return a wrapped fit function which converts the + input data into the correct shape for the optimizer, wraps the + fit function to re-constitute the independent variables and once + the fit is completed, reshape the inputs to those expected. """ @functools.wraps(self._minimizer.fit) @@ -211,20 +211,25 @@ def inner_fit_callable( vectorized: bool = False, **kwargs, ) -> FitResults: - """ - This is a wrapped callable which performs the actual fitting. It is split into + """This is a wrapped callable which performs the actual + fitting. It is split into. + 3 sections, PRE/ FIT/ POST. - PRE = Reshaping the input data into the correct dimensions for the optimizer - FIT = Wrapping the fit function and performing the fit - POST = Reshaping the outputs so it is coherent with the inputs. """ # Precompute - Reshape all independents into the correct dimensionality - x_fit, x_new, y_new, weights, dims = self._precompute_reshaping(x, y, weights, vectorized) + x_fit, x_new, y_new, weights, dims = self._precompute_reshaping( + x, y, weights, vectorized + ) self._dependent_dims = dims # Fit fit_fun_org = self._fit_function - fit_fun_wrap = self._fit_function_wrapper(x_new, flatten=True) # This should be wrapped. + fit_fun_wrap = self._fit_function_wrapper( + x_new, flatten=True + ) # This should be wrapped. self.fit_function = fit_fun_wrap f_res = self._minimizer.fit( x_fit, @@ -250,8 +255,8 @@ def _precompute_reshaping( weights: Optional[np.ndarray], vectorized: bool, ): - """ - Check the dimensions of the inputs and reshape if necessary. + """Check the dimensions of the inputs and reshape if necessary. + :param x: ND matrix of dependent points :param y: N-1D matrix of independent points :param kwargs: Additional key-word arguments @@ -293,9 +298,11 @@ def _precompute_reshaping( return x_for_fit, x_new, y_new, weights, x_shape @staticmethod - def _post_compute_reshaping(fit_result: FitResults, x: np.ndarray, y: np.ndarray) -> FitResults: - """ - Reshape the output of the fitter into the correct dimensions. + def _post_compute_reshaping( + fit_result: FitResults, x: np.ndarray, y: np.ndarray + ) -> FitResults: + """Reshape the output of the fitter into the correct dimensions. + :param fit_result: Output from the fitter :param x: Input x independent :param y: Input y dependent diff --git a/src/easyscience/fitting/minimizers/__init__.py b/src/easyscience/fitting/minimizers/__init__.py index 5ca5ee06..ca70e748 100644 --- a/src/easyscience/fitting/minimizers/__init__.py +++ b/src/easyscience/fitting/minimizers/__init__.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from .minimizer_base import MinimizerBase from .minimizer_bumps import Bumps diff --git a/src/easyscience/fitting/minimizers/factory.py b/src/easyscience/fitting/minimizers/factory.py index 2797f61d..335d288c 100644 --- a/src/easyscience/fitting/minimizers/factory.py +++ b/src/easyscience/fitting/minimizers/factory.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from typing import Callable from .. import available_minimizers @@ -12,7 +15,9 @@ from .minimizer_bumps import Bumps -def factory(minimizer_enum: AvailableMinimizers, fit_object, fit_function: Callable) -> MinimizerBase: +def factory( + minimizer_enum: AvailableMinimizers, fit_object, fit_function: Callable +) -> MinimizerBase: if minimizer_enum.package == 'lm': minimizer = LMFit(obj=fit_object, fit_function=fit_function, minimizer_enum=minimizer_enum) diff --git a/src/easyscience/fitting/minimizers/minimizer_base.py b/src/easyscience/fitting/minimizers/minimizer_base.py index 0b864657..b4539ac4 100644 --- a/src/easyscience/fitting/minimizers/minimizer_base.py +++ b/src/easyscience/fitting/minimizers/minimizer_base.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from abc import ABCMeta from abc import abstractmethod @@ -28,8 +27,8 @@ class MinimizerBase(metaclass=ABCMeta): - """ - This template class is the basis for all minimizer engines in `EasyScience`. + """This template class is the basis for all minimizer engines in + `EasyScience`. """ package: str = None @@ -72,8 +71,7 @@ def fit( max_evaluations: Optional[int] = None, **kwargs, ) -> FitResults: - """ - Perform a fit using the engine. + """Perform a fit using the engine. :param x: points to be calculated at :type x: np.ndarray @@ -89,10 +87,13 @@ def fit( :return: Fit results """ - def evaluate(self, x: np.ndarray, minimizer_parameters: Optional[dict[str, float]] = None, **kwargs) -> np.ndarray: - """ - Evaluate the fit function for values of x. Parameters used are either the latest or user supplied. - If the parameters are user supplied, it must be in a dictionary of {'parameter_name': parameter_value,...}. + def evaluate( + self, x: np.ndarray, minimizer_parameters: Optional[dict[str, float]] = None, **kwargs + ) -> np.ndarray: + """Evaluate the fit function for values of x. Parameters used + are either the latest or user supplied. If the parameters are + user supplied, it must be in a dictionary of {'parameter_name': + parameter_value,...}. :param x: x values for which the fit function will be evaluated :type x: np.ndarray @@ -129,10 +130,11 @@ def _get_method_kwargs(self, passed_method: Optional[str] = None) -> dict[str, s @abstractmethod def convert_to_pars_obj(self, par_list: Optional[Union[list]] = None): - """ - Create an engine compatible container with the `Parameters` converted from the base object. + """Create an engine compatible container with the `Parameters` + converted from the base object. - :param par_list: If only a single/selection of parameter is required. Specify as a list + :param par_list: If only a single/selection of parameter is + required. Specify as a list :type par_list: List[str] :return: engine Parameters compatible object """ @@ -140,8 +142,7 @@ def convert_to_pars_obj(self, par_list: Optional[Union[list]] = None): @staticmethod @abstractmethod def supported_methods() -> List[str]: - """ - Return a list of supported methods for the minimizer. + """Return a list of supported methods for the minimizer. :return: List of supported methods :rtype: List[str] @@ -150,8 +151,7 @@ def supported_methods() -> List[str]: @staticmethod @abstractmethod def all_methods() -> List[str]: - """ - Return a list of all available methods for the minimizer. + """Return a list of all available methods for the minimizer. :return: List of all available methods :rtype: List[str] @@ -160,15 +160,15 @@ def all_methods() -> List[str]: @staticmethod @abstractmethod def convert_to_par_object(obj): # todo after constraint changes, add type hint: obj: ObjBase - """ - Convert an `EasyScience.variable.Parameter` object to an engine Parameter object. + """Convert an `EasyScience.variable.Parameter` object to an + engine Parameter object. """ def _prepare_parameters(self, parameters: dict[str, float]) -> dict[str, float]: - """ - Prepare the parameters for the minimizer. + """Prepare the parameters for the minimizer. - :param parameters: Dict of parameters for the minimizer with names as keys. + :param parameters: Dict of parameters for the minimizer with + names as keys. """ pars = self._cached_pars @@ -179,9 +179,8 @@ def _prepare_parameters(self, parameters: dict[str, float]) -> dict[str, float]: return parameters def _generate_fit_function(self) -> Callable: - """ - Using the user supplied `fit_function`, wrap it in such a way we can update `Parameter` on - iterations. + """Using the user supplied `fit_function`, wrap it in such a way + we can update `Parameter` on iterations. :return: a fit function which is compatible with bumps models """ @@ -197,8 +196,8 @@ def _generate_fit_function(self) -> Callable: # Make a new fit function def _fit_function(x: np.ndarray, **kwargs): - """ - Wrapped fit function which now has an EasyScience compatible form + """Wrapped fit function which now has an EasyScience + compatible form. :param x: array of data points to be calculated :type x: np.ndarray @@ -227,14 +226,16 @@ def _fit_function(x: np.ndarray, **kwargs): @staticmethod def _create_signature(parameters: Dict[int, Parameter]) -> Signature: - """ - Wrap the function signature. + """Wrap the function signature. + This is done as lmfit wants the function to be in the form: f = (x, a=1, b=2)... Where we need to be generic. Note that this won't hold for much outside of this scope. """ wrapped_parameters = [] - wrapped_parameters.append(InspectParameter('x', InspectParameter.POSITIONAL_OR_KEYWORD, annotation=_empty)) + wrapped_parameters.append( + InspectParameter('x', InspectParameter.POSITIONAL_OR_KEYWORD, annotation=_empty) + ) for name, parameter in parameters.items(): default_value = parameter.value @@ -250,7 +251,9 @@ def _create_signature(parameters: Dict[int, Parameter]) -> Signature: return Signature(wrapped_parameters) @staticmethod - def _error_from_jacobian(jacobian: np.ndarray, residuals: np.ndarray, confidence: float = 0.95) -> np.ndarray: + def _error_from_jacobian( + jacobian: np.ndarray, residuals: np.ndarray, confidence: float = 0.95 + ) -> np.ndarray: from scipy import stats JtJi = np.linalg.inv(np.dot(jacobian.T, jacobian)) diff --git a/src/easyscience/fitting/minimizers/minimizer_bumps.py b/src/easyscience/fitting/minimizers/minimizer_bumps.py index 3315d2eb..37f8873e 100644 --- a/src/easyscience/fitting/minimizers/minimizer_bumps.py +++ b/src/easyscience/fitting/minimizers/minimizer_bumps.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause import copy from typing import Callable @@ -43,8 +42,8 @@ def __init__( fit_function: Callable, minimizer_enum: Optional[AvailableMinimizers] = None, ): # todo after constraint changes, add type hint: obj: ObjBase # noqa: E501 - """ - Initialize the fitting engine with a `ObjBase` and an arbitrary fitting function. + """Initialize the fitting engine with a `ObjBase` and an + arbitrary fitting function. :param obj: Object containing elements of the `Parameter` class :type obj: ObjBase @@ -80,8 +79,7 @@ def fit( engine_kwargs: Optional[dict] = None, **kwargs, ) -> FitResults: - """ - Perform a fit using the lmfit engine. + """Perform a fit using the lmfit engine. :param x: points to be calculated at :type x: np.ndarray @@ -97,12 +95,10 @@ def fit( :param method: Method for minimization :type method: str :return: Fit results - :rtype: ModelResult - - For standard least squares, the weights should be 1/sigma, where - sigma is the standard deviation of the measurement. For - unweighted least squares, these should be 1. - + :rtype: ModelResult For standard least squares, the weights + should be 1/sigma, where sigma is the standard deviation of + the measurement. For unweighted least squares, these should + be 1. """ method_dict = self._get_method_kwargs(method) @@ -129,7 +125,9 @@ def fit( if tolerance is not None: minimizer_kwargs['ftol'] = tolerance # tolerance for change in function value - minimizer_kwargs['xtol'] = tolerance # tolerance for change in parameter value, could be an independent value + minimizer_kwargs['xtol'] = ( + tolerance # tolerance for change in parameter value, could be an independent value + ) if max_evaluations is not None: minimizer_kwargs['steps'] = max_evaluations @@ -158,10 +156,11 @@ def fit( return results def convert_to_pars_obj(self, par_list: Optional[List] = None) -> List[BumpsParameter]: - """ - Create a container with the `Parameters` converted from the base object. + """Create a container with the `Parameters` converted from the + base object. - :param par_list: If only a single/selection of parameter is required. Specify as a list + :param par_list: If only a single/selection of parameter is + required. Specify as a list :type par_list: List[str] :return: bumps Parameters list :rtype: List[BumpsParameter] @@ -175,8 +174,8 @@ def convert_to_pars_obj(self, par_list: Optional[List] = None) -> List[BumpsPara # For some reason I have to double staticmethod :-/ @staticmethod def convert_to_par_object(obj) -> BumpsParameter: - """ - Convert an `EasyScience.variable.Parameter` object to a bumps Parameter object + """Convert an `EasyScience.variable.Parameter` object to a bumps + Parameter object. :return: bumps Parameter compatible object. :rtype: BumpsParameter @@ -192,9 +191,9 @@ def convert_to_par_object(obj) -> BumpsParameter: ) def _make_model(self, parameters: Optional[List[BumpsParameter]] = None) -> Callable: - """ - Generate a bumps model from the supplied `fit_function` and parameters in the base object. - Note that this makes a callable as it needs to be initialized with *x*, *y*, *weights* + """Generate a bumps model from the supplied `fit_function` and + parameters in the base object. Note that this makes a callable + as it needs to be initialized with *x*, *y*, *weights* Weights are converted to dy (standard deviation of y). @@ -208,19 +207,25 @@ def _make_func(x, y, weights): bumps_pars = {} if not parameters: for name, par in obj._cached_pars.items(): - bumps_pars[MINIMIZER_PARAMETER_PREFIX + str(name)] = obj.convert_to_par_object(par) + bumps_pars[MINIMIZER_PARAMETER_PREFIX + str(name)] = ( + obj.convert_to_par_object(par) + ) else: for par in parameters: - bumps_pars[MINIMIZER_PARAMETER_PREFIX + par.unique_name] = obj.convert_to_par_object(par) + bumps_pars[MINIMIZER_PARAMETER_PREFIX + par.unique_name] = ( + obj.convert_to_par_object(par) + ) return Curve(fit_func, x, y, dy=1 / weights, **bumps_pars) return _make_func return _outer(self) - def _set_parameter_fit_result(self, fit_result, stack_status: bool, par_list: List[BumpsParameter]): - """ - Update parameters to their final values and assign a std error to them. + def _set_parameter_fit_result( + self, fit_result, stack_status: bool, par_list: List[BumpsParameter] + ): + """Update parameters to their final values and assign a std + error to them. :param fit_result: Fit object which contains info on the fit :return: None @@ -245,8 +250,7 @@ def _set_parameter_fit_result(self, fit_result, stack_status: bool, par_list: Li global_object.stack.endMacro() def _gen_fit_results(self, fit_results, **kwargs) -> FitResults: - """ - Convert fit results into the unified `FitResults` format + """Convert fit results into the unified `FitResults` format. :param fit_result: Fit object which contains info on the fit :return: fit results container diff --git a/src/easyscience/fitting/minimizers/minimizer_dfo.py b/src/easyscience/fitting/minimizers/minimizer_dfo.py index dacef618..a480c823 100644 --- a/src/easyscience/fitting/minimizers/minimizer_dfo.py +++ b/src/easyscience/fitting/minimizers/minimizer_dfo.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from typing import Callable from typing import Dict @@ -34,8 +33,8 @@ def __init__( fit_function: Callable, minimizer_enum: Optional[AvailableMinimizers] = None, ): # todo after constraint changes, add type hint: obj: ObjBase # noqa: E501 - """ - Initialize the fitting engine with a `ObjBase` and an arbitrary fitting function. + """Initialize the fitting engine with a `ObjBase` and an + arbitrary fitting function. :param obj: Object containing elements of the `Parameter` class :type obj: ObjBase @@ -67,8 +66,7 @@ def fit( max_evaluations: Optional[int] = None, **kwargs, ) -> FitResults: - """ - Perform a fit using the DFO-ls engine. + """Perform a fit using the DFO-ls engine. :param x: points to be calculated at :type x: np.ndarray @@ -84,11 +82,10 @@ def fit( :param method: Method for minimization :type method: str :return: Fit results - :rtype: ModelResult - - For standard least squares, the weights should be 1/sigma, where - sigma is the standard deviation of the measurement. For - unweighted least squares, these should be 1. + :rtype: ModelResult For standard least squares, the weights + should be 1/sigma, where sigma is the standard deviation of + the measurement. For unweighted least squares, these should + be 1. """ x, y, weights = np.asarray(x), np.asarray(y), np.asarray(weights) @@ -132,22 +129,18 @@ def fit( return results def convert_to_pars_obj(self, par_list: Optional[list] = None): - """ - Required by interface but not needed for DFO-LS - """ + """Required by interface but not needed for DFO-LS.""" pass @staticmethod def convert_to_par_object(obj) -> None: - """ - Required by interface but not needed for DFO-LS - """ + """Required by interface but not needed for DFO-LS.""" pass def _make_model(self, parameters: Optional[List[Parameter]] = None) -> Callable: - """ - Generate a model from the supplied `fit_function` and parameters in the base object. - Note that this makes a callable as it needs to be initialized with *x*, *y*, *weights* + """Generate a model from the supplied `fit_function` and + parameters in the base object. Note that this makes a callable + as it needs to be initialized with *x*, *y*, *weights* :return: Callable model which returns residuals :rtype: Callable @@ -176,11 +169,12 @@ def _residuals(pars_values: List[float]) -> np.ndarray: return _outer(self) def _set_parameter_fit_result(self, fit_result, stack_status, ci: float = 0.95) -> None: - """ - Update parameters to their final values and assign a std error to them. + """Update parameters to their final values and assign a std + error to them. :param fit_result: Fit object which contains info on the fit - :param ci: Confidence interval for calculating errors. Default 95% + :param ci: Confidence interval for calculating errors. Default + 95% :return: None :rtype: noneType """ @@ -203,8 +197,7 @@ def _set_parameter_fit_result(self, fit_result, stack_status, ci: float = 0.95) global_object.stack.endMacro() def _gen_fit_results(self, fit_results, weights, **kwargs) -> FitResults: - """ - Convert fit results into the unified `FitResults` format + """Convert fit results into the unified `FitResults` format. :param fit_result: Fit object which contains info on the fit :return: fit results container @@ -242,8 +235,8 @@ def _dfo_fit( model: Callable, **kwargs, ): - """ - Method to convert EasyScience styling to DFO-LS styling (yes, again) + """Method to convert EasyScience styling to DFO-LS styling (yes, + again) :param model: Model which accepts f(x[0]) :type model: Callable diff --git a/src/easyscience/fitting/minimizers/minimizer_lmfit.py b/src/easyscience/fitting/minimizers/minimizer_lmfit.py index 2c63cea3..4a8104b2 100644 --- a/src/easyscience/fitting/minimizers/minimizer_lmfit.py +++ b/src/easyscience/fitting/minimizers/minimizer_lmfit.py @@ -1,7 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from typing import Callable from typing import List @@ -38,10 +36,11 @@ def __init__( fit_function: Callable, minimizer_enum: Optional[AvailableMinimizers] = None, ): # todo after constraint changes, add type hint: obj: ObjBase # noqa: E501 - """ - Initialize the minimizer with the `ObjBase` and the `fit_function` to be used. + """Initialize the minimizer with the `ObjBase` and the + `fit_function` to be used. - :param obj: Base object which contains the parameters to be fitted + :param obj: Base object which contains the parameters to be + fitted :type obj: ObjBase :param fit_function: Function which will be fitted to the data :type fit_function: Callable @@ -91,8 +90,7 @@ def fit( engine_kwargs: Optional[dict] = None, **kwargs, ) -> FitResults: - """ - Perform a fit using the lmfit engine. + """Perform a fit using the lmfit engine. :param method: :type method: @@ -106,16 +104,15 @@ def fit( :type model: LMModel :param parameters: Optional parameters for the fit :type parameters: LMParameters - :param minimizer_kwargs: Arguments to be passed directly to the minimizer + :param minimizer_kwargs: Arguments to be passed directly to the + minimizer :type minimizer_kwargs: dict :param kwargs: Additional arguments for the fitting function. :return: Fit results - :rtype: ModelResult - - For standard least squares, the weights should be 1/sigma, where - sigma is the standard deviation of the measurement. For - unweighted least squares, these should be 1. - + :rtype: ModelResult For standard least squares, the weights + should be 1/sigma, where sigma is the standard deviation of + the measurement. For unweighted least squares, these should + be 1. """ x, y, weights = np.asarray(x), np.asarray(y), np.asarray(weights) @@ -165,7 +162,9 @@ def fit( raise FitError(e) return results - def _get_fit_kws(self, method: str, tolerance: float, minimizer_kwargs: dict[str:str]) -> dict[str:str]: + def _get_fit_kws( + self, method: str, tolerance: float, minimizer_kwargs: dict[str:str] + ) -> dict[str:str]: if minimizer_kwargs is None: minimizer_kwargs = {} if tolerance is not None: @@ -176,22 +175,25 @@ def _get_fit_kws(self, method: str, tolerance: float, minimizer_kwargs: dict[str return minimizer_kwargs def convert_to_pars_obj(self, parameters: Optional[List[Parameter]] = None) -> LMParameters: - """ - Create an lmfit compatible container with the `Parameters` converted from the base object. + """Create an lmfit compatible container with the `Parameters` + converted from the base object. - :param parameters: If only a single/selection of parameter is required. Specify as a list + :param parameters: If only a single/selection of parameter is + required. Specify as a list :return: lmfit Parameters compatible object """ if parameters is None: # Assume that we have a ObjBase for which we can obtain a list parameters = self._object.get_fit_parameters() - lm_parameters = LMParameters().add_many([self.convert_to_par_object(parameter) for parameter in parameters]) + lm_parameters = LMParameters().add_many([ + self.convert_to_par_object(parameter) for parameter in parameters + ]) return lm_parameters @staticmethod def convert_to_par_object(parameter: Parameter) -> LMParameter: - """ - Convert an EasyScience Parameter object to a lmfit Parameter object. + """Convert an EasyScience Parameter object to a lmfit Parameter + object. :return: lmfit Parameter compatible object. :rtype: LMParameter @@ -209,8 +211,8 @@ def convert_to_par_object(parameter: Parameter) -> LMParameter: ) def _make_model(self, pars: Optional[LMParameters] = None) -> LMModel: - """ - Generate a lmfit model from the supplied `fit_function` and parameters in the base object. + """Generate a lmfit model from the supplied `fit_function` and + parameters in the base object. :return: Callable lmfit model :rtype: LMModel @@ -247,8 +249,8 @@ def _make_model(self, pars: Optional[LMParameters] = None) -> LMModel: return model def _set_parameter_fit_result(self, fit_result: ModelResult, stack_status: bool): - """ - Update parameters to their final values and assign a std error to them. + """Update parameters to their final values and assign a std + error to them. :param fit_result: Fit object which contains info on the fit :return: None diff --git a/src/easyscience/fitting/minimizers/utils.py b/src/easyscience/fitting/minimizers/utils.py index 60ab00a6..76449a17 100644 --- a/src/easyscience/fitting/minimizers/utils.py +++ b/src/easyscience/fitting/minimizers/utils.py @@ -1,9 +1,12 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import numpy as np class FitResults: - """ - At the moment this is just a dummy way of unifying the returned fit parameters. + """At the moment this is just a dummy way of unifying the returned + fit parameters. """ __slots__ = [ diff --git a/src/easyscience/fitting/multi_fitter.py b/src/easyscience/fitting/multi_fitter.py index a30bdcec..94e715c6 100644 --- a/src/easyscience/fitting/multi_fitter.py +++ b/src/easyscience/fitting/multi_fitter.py @@ -1,6 +1,6 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause + from typing import Callable from typing import List from typing import Optional @@ -13,8 +13,10 @@ class MultiFitter(Fitter): - """ - Extension of Fitter to enable multiple dataset/fit function fitting. We can fit these types of data simultaneously: + """Extension of Fitter to enable multiple dataset/fit function + fitting. + + We can fit these types of data simultaneously: - Multiple models on multiple datasets. """ @@ -31,9 +33,10 @@ def __init__( super().__init__(self._fit_objects, self._fit_functions[0]) def _fit_function_wrapper(self, real_x=None, flatten: bool = True) -> Callable: - """ - Simple fit function which injects the N real X (independent) values into the - optimizer function. This will also flatten the results if needed. + """Simple fit function which injects the N real X (independent) + values into the optimizer function. + + This will also flatten the results if needed. :param real_x: List of independent x parameters to be injected :param flatten: Should the result be a flat 1D array? :return: Wrapped optimizer function. @@ -65,8 +68,9 @@ def _precompute_reshaping( weights: Optional[List[np.ndarray]], vectorized: bool, ): - """ - Convert an array of X's and Y's to an acceptable shape for fitting. + """Convert an array of X's and Y's to an acceptable shape for + fitting. + :param x: List of independent variables. :param y: List of dependent variables. :param vectorized: Is the fn input vectorized or point based? @@ -75,13 +79,17 @@ def _precompute_reshaping( """ if weights is None: weights = [None] * len(x) - _, _x_new, _y_new, _weights, _dims = Fitter._precompute_reshaping(x[0], y[0], weights[0], vectorized) + _, _x_new, _y_new, _weights, _dims = Fitter._precompute_reshaping( + x[0], y[0], weights[0], vectorized + ) x_new = [_x_new] y_new = [_y_new] w_new = [_weights] dims = [_dims] for _x, _y, _w in zip(x[1::], y[1::], weights[1::]): - _, _x_new, _y_new, _weights, _dims = Fitter._precompute_reshaping(_x, _y, _w, vectorized) + _, _x_new, _y_new, _weights, _dims = Fitter._precompute_reshaping( + _x, _y, _w, vectorized + ) x_new.append(_x_new) y_new.append(_y_new) w_new.append(_weights) @@ -100,12 +108,10 @@ def _post_compute_reshaping( x: List[np.ndarray], y: List[np.ndarray], ) -> List[FitResults]: - """ - Take a fit results object and split it into n chuncks based on the size of the x, y inputs - :param fit_result_obj: Result from a multifit - :param x: List of X co-ords - :param y: List of Y co-ords - :return: List of fit results + """Take a fit results object and split it into n chuncks based + on the size of the x, y inputs :param fit_result_obj: Result + from a multifit :param x: List of X co-ords :param y: List of Y + co-ords :return: List of fit results. """ cls = fit_result_obj.__class__ @@ -123,8 +129,12 @@ def _post_compute_reshaping( current_results.p0 = fit_result_obj.p0 current_results.x = this_x current_results.y_obs = y[idx] - current_results.y_calc = np.reshape(fit_result_obj.y_calc[sp:ep], current_results.y_obs.shape) - current_results.y_err = np.reshape(fit_result_obj.y_err[sp:ep], current_results.y_obs.shape) + current_results.y_calc = np.reshape( + fit_result_obj.y_calc[sp:ep], current_results.y_obs.shape + ) + current_results.y_err = np.reshape( + fit_result_obj.y_err[sp:ep], current_results.y_obs.shape + ) current_results.engine_result = fit_result_obj.engine_result # Attach an additional field for the un-modified results diff --git a/src/easyscience/global_object/__init__.py b/src/easyscience/global_object/__init__.py index 2adc1bc2..c0934dde 100644 --- a/src/easyscience/global_object/__init__.py +++ b/src/easyscience/global_object/__init__.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from .global_object import GlobalObject # noqa: F401 from .hugger.hugger import ScriptManager # noqa: F401 from .logger import Logger # noqa: F401 diff --git a/src/easyscience/global_object/global_object.py b/src/easyscience/global_object/global_object.py index 63726d01..dbaa994d 100644 --- a/src/easyscience/global_object/global_object.py +++ b/src/easyscience/global_object/global_object.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from ..utils.classUtils import singleton from .hugger.hugger import ScriptManager @@ -10,8 +9,9 @@ @singleton class GlobalObject: - """ - GlobalObject is the assimilated knowledge of `EasyScience`. Every class based on `EasyScience` gets brought + """GlobalObject is the assimilated knowledge of `EasyScience`. + + Every class based on `EasyScience` gets brought into the collective. """ @@ -33,9 +33,8 @@ def __init__(self): self.map: Map = self.__map def instantiate_stack(self): - """ - The undo/redo stack references the collective. Hence it has to be imported - after initialization. + """The undo/redo stack references the collective. Hence it has + to be imported after initialization. :return: None :rtype: noneType @@ -45,13 +44,15 @@ def instantiate_stack(self): self.stack = UndoStack() def generate_unique_name(self, name_prefix: str) -> str: - """ - Generate a generic unique name for the object using the class name and a global iterator. - Names are in the format `name_prefix_0`, `name_prefix_1`, `name_prefix_2`, etc. + """Generate a generic unique name for the object using the class + name and a global iterator. Names are in the format + `name_prefix_0`, `name_prefix_1`, `name_prefix_2`, etc. :param name_prefix: The prefix to be used for the name """ - names_with_prefix = [name for name in self.map.vertices() if name.startswith(name_prefix + '_')] + names_with_prefix = [ + name for name in self.map.vertices() if name.startswith(name_prefix + '_') + ] if names_with_prefix: name_with_prefix_count = [0] for name in names_with_prefix: diff --git a/src/easyscience/global_object/hugger/__init__.py b/src/easyscience/global_object/hugger/__init__.py index 867a21c4..b1990ec8 100644 --- a/src/easyscience/global_object/hugger/__init__.py +++ b/src/easyscience/global_object/hugger/__init__.py @@ -1,4 +1,3 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause diff --git a/src/easyscience/global_object/hugger/hugger.py b/src/easyscience/global_object/hugger/hugger.py index 193482c8..42bf4497 100644 --- a/src/easyscience/global_object/hugger/hugger.py +++ b/src/easyscience/global_object/hugger/hugger.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause import inspect import sys @@ -94,9 +93,12 @@ def is_mutable(arg) -> bool: @staticmethod def _caller_name(skip: int = 2): """Get a name of a caller in the format module.class.method - `skip` specifies how many levels of stack to skip while getting caller - name. skip=1 means "who calls me", skip=2 "who calls my caller" etc. - An empty string is returned if skipped levels exceed stack height + `skip` specifies how many levels of stack to skip while getting + caller name. + + skip=1 means "who calls me", skip=2 "who calls my caller" etc. + An empty string is returned if skipped levels exceed stack + height https://gist.github.com/techtonik/2151727#gistcomment-2333747 """ diff --git a/src/easyscience/global_object/hugger/property.py b/src/easyscience/global_object/hugger/property.py index a18f913b..2367d1fb 100644 --- a/src/easyscience/global_object/hugger/property.py +++ b/src/easyscience/global_object/hugger/property.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause import sys from functools import wraps @@ -15,8 +14,9 @@ class LoggedProperty(property): - """ - Pump up python properties. In this case we can see who has called this property and + """Pump up python properties. + + In this case we can see who has called this property and then do something if a criteria is met. In this case if the caller is not a member of the `ObjBase` class. Note that all high level `EasyScience` objects should be built from `ObjBase`. @@ -81,7 +81,9 @@ def __set__(self, instance, value): if not test and self._get_id is not None and self._my_self is not None: Store().append_log(self.makeEntry('set', value)) if global_object.debug: # noqa: S1006 - print(f"I'm {self._my_self} and {self._get_id} has been set to {value} from the outside!") + print( + f"I'm {self._my_self} and {self._get_id} has been set to {value} from the outside!" + ) return super().__set__(instance, value) def makeEntry(self, log_type, returns, *args, **kwargs) -> str: @@ -174,7 +176,9 @@ def patch_get(self, func: Callable) -> Callable: @wraps(func) def inner(*args, **kwargs): if global_object.debug: - print(f'{self.klass.__name__}.{self.prop_name} has been called with {args[1:]}, {kwargs}') + print( + f'{self.klass.__name__}.{self.prop_name} has been called with {args[1:]}, {kwargs}' + ) res = func(*args, **kwargs) self._append_args(*args, **kwargs) self._append_result(res) @@ -187,7 +191,9 @@ def patch_set(self, func: Callable) -> Callable: @wraps(func) def inner(*args, **kwargs): if global_object.debug: - print(f'{self.klass.__name__}.{self.prop_name} has been set with {args[1:]}, {kwargs}') + print( + f'{self.klass.__name__}.{self.prop_name} has been set with {args[1:]}, {kwargs}' + ) self._append_args(*args, **kwargs) self._append_log(self.makeEntry('set', None, *args, **kwargs)) return func(*args, **kwargs) diff --git a/src/easyscience/global_object/logger.py b/src/easyscience/global_object/logger.py index f4fa3a42..0400d524 100644 --- a/src/easyscience/global_object/logger.py +++ b/src/easyscience/global_object/logger.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause import logging @@ -12,11 +11,11 @@ def __init__(self, log_level: int = logging.INFO): self.logger.setLevel(self.level) def getLogger(self, logger_name, color: str = '32', defaults: bool = True) -> logging: - """ - Create a logger - :param color: + """Create a logger :param color: + :param logger_name: logger name. Usually __name__ on creation - :param defaults: Do you want to associate any current file loggers with this logger + :param defaults: Do you want to associate any current file + loggers with this logger :return: A logger """ logger = logging.getLogger(logger_name) diff --git a/src/easyscience/global_object/map.py b/src/easyscience/global_object/map.py index a9d0b576..c9172c09 100644 --- a/src/easyscience/global_object/map.py +++ b/src/easyscience/global_object/map.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause import gc import sys @@ -79,7 +78,8 @@ def _snapshot_items(self): Some callers iterate over __type_dict while other threads or weakref finalizers may modify it. Creating a list snapshot (with - a retry loop) prevents RuntimeError: dictionary changed size during iteration. + a retry loop) prevents RuntimeError: dictionary changed size + during iteration. """ while True: try: @@ -92,7 +92,8 @@ def vertices(self) -> List[str]: """Returns the vertices of a map. Uses a retry loop to handle RuntimeError that can occur when the - WeakValueDictionary is modified during iteration (e.g., by garbage collection). + WeakValueDictionary is modified during iteration (e.g., by + garbage collection). """ while True: try: @@ -102,7 +103,7 @@ def vertices(self) -> List[str]: continue def edges(self): - """returns the edges of a map""" + """Returns the edges of a map.""" return self.__generate_edges() @property @@ -186,10 +187,10 @@ def get_edges(self, start_obj) -> List[str]: raise AttributeError def __generate_edges(self) -> list: - """A static method generating the edges of the - map. Edges are represented as sets - with one (a loop back to the vertex) or two - vertices + """A static method generating the edges of the map. + + Edges are represented as sets with one (a loop back to the + vertex) or two vertices """ edges = [] # Iterate over a snapshot of items and snapshot neighbour lists to @@ -221,7 +222,7 @@ def prune(self, key: str): del self._store[key] def find_isolated_vertices(self) -> list: - """returns a list of isolated vertices.""" + """Returns a list of isolated vertices.""" isolated = [] for vertex, neighbours in self._snapshot_items(): if not list(neighbours): @@ -229,8 +230,7 @@ def find_isolated_vertices(self) -> list: return isolated def find_path(self, start_vertex: str, end_vertex: str, path=[]) -> list: - """find a path from start_vertex to end_vertex - in map""" + """Find a path from start_vertex to end_vertex in map.""" graph = self.__type_dict path = path + [start_vertex] @@ -246,8 +246,7 @@ def find_path(self, start_vertex: str, end_vertex: str, path=[]) -> list: return [] def find_all_paths(self, start_vertex: str, end_vertex: str, path=[]) -> list: - """find all paths from start_vertex to - end_vertex in map""" + """Find all paths from start_vertex to end_vertex in map.""" graph = self.__type_dict path = path + [start_vertex] @@ -264,9 +263,11 @@ def find_all_paths(self, start_vertex: str, end_vertex: str, path=[]) -> list: return paths def reverse_route(self, end_vertex: str, start_vertex: Optional[str] = None) -> List: - """ - In this case we have an object and want to know the connections to get to another in reverse. - We might not know the start_object. In which case we follow the shortest path to a base vertex. + """In this case we have an object and want to know the + connections to get to another in reverse. + + We might not know the start_object. In which case we follow the + shortest path to a base vertex. :param end_obj: :type end_obj: :param start_obj: @@ -291,7 +292,7 @@ def reverse_route(self, end_vertex: str, start_vertex: Optional[str] = None) -> return optimum_path def is_connected(self, vertices_encountered=None, start_vertex=None) -> bool: - """determines if the map is connected""" + """Determines if the map is connected.""" if vertices_encountered is None: vertices_encountered = set() graph = self.__type_dict @@ -302,14 +303,19 @@ def is_connected(self, vertices_encountered=None, start_vertex=None) -> bool: vertices_encountered.add(start_vertex) if len(vertices_encountered) != len(vertices): for vertex in list(graph[start_vertex]): - if vertex not in vertices_encountered and self.is_connected(vertices_encountered, vertex): + if vertex not in vertices_encountered and self.is_connected( + vertices_encountered, vertex + ): return True else: return True return False def _clear(self): - """Reset the map to an empty state. Only to be used for testing""" + """Reset the map to an empty state. + + Only to be used for testing + """ self._store.clear() self.__type_dict.clear() gc.collect() diff --git a/src/easyscience/global_object/undo_redo.py b/src/easyscience/global_object/undo_redo.py index 7317ec23..bb1e173c 100644 --- a/src/easyscience/global_object/undo_redo.py +++ b/src/easyscience/global_object/undo_redo.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause import abc import functools @@ -19,9 +18,7 @@ class UndoCommand(metaclass=abc.ABCMeta): - """ - The Command interface pattern - """ + """The Command interface pattern.""" def __init__(self, obj) -> None: self._obj = obj @@ -29,15 +26,11 @@ def __init__(self, obj) -> None: @abc.abstractmethod def undo(self) -> NoReturn: - """ - Undo implementation which should be overwritten - """ + """Undo implementation which should be overwritten.""" @abc.abstractmethod def redo(self) -> NoReturn: - """ - Redo implementation which should be overwritten - """ + """Redo implementation which should be overwritten.""" @property def text(self) -> str: @@ -68,8 +61,9 @@ def inner(obj, *args, **kwargs): class NotarizedDict(UserDict): - """ - A simple dict drop in for EasyScience group classes. This is used as it wraps the get/set methods + """A simple dict drop in for EasyScience group classes. + + This is used as it wraps the get/set methods """ def __init__(self, **kwargs): @@ -101,8 +95,8 @@ def reorder(self, **kwargs): class CommandHolder: - """ - A holder for one or more commands which are added to the stack + """A holder for one or more commands which are added to the + stack. """ def __init__(self, text: str = None): @@ -149,9 +143,7 @@ def text(self, text: str): class UndoStack: - """ - Implement a version of QUndoStack without the QT - """ + """Implement a version of QUndoStack without the QT.""" def __init__(self, max_history: Union[int, type(None)] = None): self._history = deque(maxlen=max_history) @@ -183,9 +175,7 @@ def future(self) -> deque: return self._future def push(self, command: T_) -> NoReturn: - """ - Add a command to the history stack - """ + """Add a command to the history stack.""" # If we're not enabled, then what are we doing! if not self.enabled or self._command_running: # Do the command and leave. @@ -220,17 +210,13 @@ def pop(self) -> T_: return popped def clear(self) -> None: # NoReturn: - """ - Remove any commands on the stack and reset the state - """ + """Remove any commands on the stack and reset the state.""" self._history = deque(maxlen=self._max_history) self._future = deque(maxlen=self._max_history) self._macro_running = False def undo(self) -> NoReturn: - """ - Undo the last change to the stack - """ + """Undo the last change to the stack.""" if self.canUndo(): # Move the command from the past to the future this_command_stack = self._history.popleft() @@ -247,9 +233,7 @@ def undo(self) -> NoReturn: self._command_running = False def redo(self) -> NoReturn: - """ - Redo the last `undo` command on the stack - """ + """Redo the last `undo` command on the stack.""" if self.canRedo(): # Move from the future to the past this_command_stack = self._future.popleft() @@ -267,8 +251,8 @@ def redo(self) -> NoReturn: self._command_running = False def beginMacro(self, text: str) -> NoReturn: - """ - Start a bulk update i.e. multiple commands under one undo/redo command + """Start a bulk update i.e. multiple commands under one + undo/redo command. """ if self._macro_running: raise AssertionError('Cannot start a macro when one is already running') @@ -277,38 +261,30 @@ def beginMacro(self, text: str) -> NoReturn: self._macro_running = True def endMacro(self) -> NoReturn: - """ - End a bulk update i.e. multiple commands under one undo/redo command + """End a bulk update i.e. multiple commands under one undo/redo + command. """ if not self._macro_running: raise AssertionError('Cannot end a macro when one is not running') self._macro_running = False def canUndo(self) -> bool: - """ - Can the last command be undone? - """ + """Can the last command be undone?""" return len(self._history) > 0 and not self._macro_running def canRedo(self) -> bool: - """ - Can we redo a command? - """ + """Can we redo a command?""" return len(self._future) > 0 and not self._macro_running def redoText(self) -> str: - """ - Text associated with a redo item. - """ + """Text associated with a redo item.""" text = '' if self.canRedo(): text = self.future[0].text return text def undoText(self) -> str: - """ - Text associated with a undo item. - """ + """Text associated with a undo item.""" text = '' if self.canUndo(): text = self.history[0].text @@ -316,9 +292,7 @@ def undoText(self) -> str: class PropertyStack(UndoCommand): - """ - Stack operator for when a property setter is wrapped. - """ + """Stack operator for when a property setter is wrapped.""" def __init__(self, parent, func: Callable, old_value: Any, new_value: Any, text: str = None): # self.setText("Setting {} to {}".format(func.__name__, new_value)) diff --git a/src/easyscience/io/__init__.py b/src/easyscience/io/__init__.py index b21e648c..6a53db96 100644 --- a/src/easyscience/io/__init__.py +++ b/src/easyscience/io/__init__.py @@ -1,6 +1,6 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause + from .serializer_base import SerializerBase from .serializer_component import SerializerComponent from .serializer_dict import SerializerDict diff --git a/src/easyscience/io/serializer_base.py b/src/easyscience/io/serializer_base.py index b4eeaf2a..8bcf987a 100644 --- a/src/easyscience/io/serializer_base.py +++ b/src/easyscience/io/serializer_base.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from __future__ import annotations @@ -28,21 +27,25 @@ class SerializerBase: - """ - This is the base class for creating an encoder/decoder which can convert EasyScience objects. `encode` and `decode` are + """This is the base class for creating an encoder/decoder which can + convert EasyScience objects. + + `encode` and `decode` are abstract methods to be implemented for each serializer. It is expected that the helper function `_convert_to_dict` will be used as a base for encoding (or the `SerializerDict` as it's more flexible). """ @abstractmethod def encode(self, obj: SerializerComponent, skip: Optional[List[str]] = None, **kwargs) -> any: - """ - Abstract implementation of an encoder. + """Abstract implementation of an encoder. :param obj: Object to be encoded. - :param skip: List of field names as strings to skip when forming the encoded object - :param kwargs: Any additional key word arguments to be passed to the encoder - :return: encoded object containing all information to reform an EasyScience object. + :param skip: List of field names as strings to skip when forming + the encoded object + :param kwargs: Any additional key word arguments to be passed to + the encoder + :return: encoded object containing all information to reform an + EasyScience object. """ pass @@ -50,8 +53,8 @@ def encode(self, obj: SerializerComponent, skip: Optional[List[str]] = None, **k @classmethod @abstractmethod def decode(cls, obj: Any) -> Any: - """ - Re-create an EasyScience object from the output of an encoder. The default decoder is `SerializerDict`. + """Re-create an EasyScience object from the output of an + encoder. The default decoder is `SerializerDict`. :param obj: encoded EasyScience object :return: Reformed EasyScience object @@ -60,8 +63,8 @@ def decode(cls, obj: Any) -> Any: @staticmethod def get_arg_spec(func: Callable) -> Tuple[Any, List[str]]: - """ - Get the full argument specification of a function (typically `__init__`) + """Get the full argument specification of a function (typically + `__init__`) :param func: Function to be inspected :return: Tuple of argument spec and arguments @@ -73,8 +76,7 @@ def get_arg_spec(func: Callable) -> Tuple[Any, List[str]]: @staticmethod def _encode_objs(obj: Any) -> Dict[str, Any]: - """ - A JSON serializable dict representation of an object. + """A JSON serializable dict representation of an object. :param obj: any object to be encoded :param skip: List of field names as strings to skip when forming the encoded object @@ -117,9 +119,7 @@ def _convert_to_dict( full_encode: bool = False, **kwargs, ) -> dict: - """ - A JSON serializable dict representation of an object. - """ + """A JSON serializable dict representation of an object.""" if skip is None: skip = [] @@ -189,7 +189,9 @@ def runner(o): 'determine the dict format. Alternatively, ' 'you can implement both as_dict and from_dict.' ) - d[c] = self._recursive_encoder(a, skip=skip, encoder=self, full_encode=full_encode, **kwargs) + d[c] = self._recursive_encoder( + a, skip=skip, encoder=self, full_encode=full_encode, **kwargs + ) if spec.varargs is not None and getattr(obj, spec.varargs, None) is not None: d.update({spec.varargs: getattr(obj, spec.varargs)}) if hasattr(obj, '_kwargs'): @@ -223,12 +225,11 @@ def runner(o): @staticmethod def _convert_from_dict(d): - """ - Recursive method to support decoding dicts and lists containing EasyScience objects + """Recursive method to support decoding dicts and lists + containing EasyScience objects. :param d: Dictionary containing JSONed EasyScience objects :return: Reformed EasyScience object - """ T_ = type(d) if isinstance(d, dict): @@ -249,7 +250,11 @@ def _convert_from_dict(d): mod = __import__(modname, globals(), locals(), [classname], 0) if hasattr(mod, classname): cls_ = getattr(mod, classname) - data = {k: SerializerBase._convert_from_dict(v) for k, v in d.items() if not k.startswith('@')} + data = { + k: SerializerBase._convert_from_dict(v) + for k, v in d.items() + if not k.startswith('@') + } return cls_(**data) elif np is not None and modname == 'numpy' and classname == 'array': if d['dtype'].startswith('complex'): @@ -262,20 +267,24 @@ def _convert_from_dict(d): @staticmethod def deserialize_dict(in_dict: Dict[str, Any]) -> Dict[str, Any]: - """ - Deserialize a dictionary using from_dict for ES objects and SerializerBase otherwise. - This method processes constructor arguments, skipping metadata keys starting with '@'. + """Deserialize a dictionary using from_dict for ES objects and + SerializerBase otherwise. This method processes constructor + arguments, skipping metadata keys starting with '@'. :param in_dict: dictionary to deserialize :return: deserialized dictionary with constructor arguments """ - d = {key: SerializerBase._deserialize_value(value) for key, value in in_dict.items() if not key.startswith('@')} + d = { + key: SerializerBase._deserialize_value(value) + for key, value in in_dict.items() + if not key.startswith('@') + } return d @staticmethod def _deserialize_value(value: Any) -> Any: - """ - Deserialize a single value, using specialized handling for ES objects. + """Deserialize a single value, using specialized handling for ES + objects. :param value: :return: deserialized value @@ -301,18 +310,21 @@ def _deserialize_value(value: Any) -> Any: @staticmethod def _is_serialized_easyscience_object(value: Any) -> bool: - """ - Check if a value represents a serialized ES object. + """Check if a value represents a serialized ES object. :param value: :return: True if this is a serialized ES object """ - return isinstance(value, dict) and '@module' in value and value['@module'].startswith('easy') and '@class' in value + return ( + isinstance(value, dict) + and '@module' in value + and value['@module'].startswith('easy') + and '@class' in value + ) @staticmethod def _import_class(module_name: str, class_name: str): - """ - Import a class from a module name and class name. + """Import a class from a module name and class name. :param module_name: name of the module :param class_name: name of the class @@ -330,24 +342,33 @@ def _import_class(module_name: str, class_name: str): return getattr(module, class_name) - def _recursive_encoder(self, obj, skip: List[str] = [], encoder=None, full_encode=False, **kwargs): - """ - Walk through an object encoding it - """ + def _recursive_encoder( + self, obj, skip: List[str] = [], encoder=None, full_encode=False, **kwargs + ): + """Walk through an object encoding it.""" if encoder is None: encoder = SerializerBase() T_ = type(obj) if issubclass(T_, (list, tuple, MutableSequence)): # Is it a core MutableSequence? - if hasattr(obj, 'encode') and obj.__class__.__module__ != 'builtins': # strings have encode + if ( + hasattr(obj, 'encode') and obj.__class__.__module__ != 'builtins' + ): # strings have encode return encoder._convert_to_dict(obj, skip, full_encode, **kwargs) elif hasattr(obj, 'to_dict') and obj.__class__.__module__.startswith('easy'): return encoder._convert_to_dict(obj, skip, full_encode, **kwargs) else: - return [self._recursive_encoder(it, skip, encoder, full_encode, **kwargs) for it in obj] + return [ + self._recursive_encoder(it, skip, encoder, full_encode, **kwargs) for it in obj + ] if isinstance(obj, dict): - return {kk: self._recursive_encoder(vv, skip, encoder, full_encode, **kwargs) for kk, vv in obj.items()} - if hasattr(obj, 'encode') and obj.__class__.__module__ != 'builtins': # strings have encode + return { + kk: self._recursive_encoder(vv, skip, encoder, full_encode, **kwargs) + for kk, vv in obj.items() + } + if ( + hasattr(obj, 'encode') and obj.__class__.__module__ != 'builtins' + ): # strings have encode return encoder._convert_to_dict(obj, skip, full_encode, **kwargs) elif hasattr(obj, 'to_dict') and obj.__class__.__module__.startswith('easy'): return encoder._convert_to_dict(obj, skip, full_encode, **kwargs) diff --git a/src/easyscience/io/serializer_component.py b/src/easyscience/io/serializer_component.py index 85da9961..02938a29 100644 --- a/src/easyscience/io/serializer_component.py +++ b/src/easyscience/io/serializer_component.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from __future__ import annotations @@ -17,10 +16,10 @@ class SerializerComponent: - """ - This base class adds the capability of saving and loading (encoding/decoding, serializing/deserializing) easyscience - objects via the `encode` and `decode` methods. - The default encoder is `SerializerDict`, which converts the object to a dictionary. + """This base class adds the capability of saving and loading + (encoding/decoding, serializing/deserializing) easyscience objects + via the `encode` and `decode` methods. The default encoder is + `SerializerDict`, which converts the object to a dictionary. Shortcuts for dictionary and encoding is also present. """ @@ -28,9 +27,11 @@ class SerializerComponent: def __deepcopy__(self, memo): return self.from_dict(self.as_dict()) - def encode(self, skip: Optional[List[str]] = None, encoder: Optional[SerializerBase] = None, **kwargs) -> Any: - """ - Use an encoder to covert an EasyScience object into another format. Default is to a dictionary using `SerializerDict`. + def encode( + self, skip: Optional[List[str]] = None, encoder: Optional[SerializerBase] = None, **kwargs + ) -> Any: + """Use an encoder to covert an EasyScience object into another + format. Default is to a dictionary using `SerializerDict`. :param skip: List of field names as strings to skip when forming the encoded object :param encoder: The encoder to be used for encoding the data. Default is `SerializerDict` @@ -44,11 +45,12 @@ def encode(self, skip: Optional[List[str]] = None, encoder: Optional[SerializerB @classmethod def decode(cls, obj: Any, decoder: Optional[SerializerBase] = None) -> Any: - """ - Re-create an EasyScience object from the output of an encoder. The default decoder is `SerializerDict`. + """Re-create an EasyScience object from the output of an + encoder. The default decoder is `SerializerDict`. :param obj: encoded EasyScience object - :param decoder: decoder to be used to reform the EasyScience object + :param decoder: decoder to be used to reform the EasyScience + object :return: Reformed EasyScience object """ @@ -57,20 +59,22 @@ def decode(cls, obj: Any, decoder: Optional[SerializerBase] = None) -> Any: return decoder.decode(obj) def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: - """ - Convert an EasyScience object into a full dictionary using `SerializerDict`. - This is a shortcut for ```obj.encode(encoder=SerializerDict)``` - - :param skip: List of field names as strings to skip when forming the dictionary - :return: encoded object containing all information to reform an EasyScience object. + """Convert an EasyScience object into a full dictionary using + `SerializerDict`. This is a shortcut for + ```obj.encode(encoder=SerializerDict)``` + + :param skip: List of field names as strings to skip when forming + the dictionary + :return: encoded object containing all information to reform an + EasyScience object. """ return self.encode(skip=skip, encoder=SerializerDict) @classmethod def from_dict(cls, obj_dict: Dict[str, Any]) -> None: - """ - Re-create an EasyScience object from a full encoded dictionary. + """Re-create an EasyScience object from a full encoded + dictionary. :param obj_dict: dictionary containing the serialized contents (from `SerializerDict`) of an EasyScience object :return: Reformed EasyScience object diff --git a/src/easyscience/io/serializer_dict.py b/src/easyscience/io/serializer_dict.py index 8fe423c1..8dc73a63 100644 --- a/src/easyscience/io/serializer_dict.py +++ b/src/easyscience/io/serializer_dict.py @@ -1,10 +1,10 @@ +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations __author__ = 'https://github.com/materialsvirtuallab/monty/blob/master/monty/json.py' __version__ = '3.0.0' -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project SerializerComponent: - """ - Re-create an EasyScience object from the dictionary representation. + """Re-create an EasyScience object from the dictionary + representation. :param d: Dict representation of an EasyScience object. :return: EasyScience object. diff --git a/src/easyscience/job/__init__.py b/src/easyscience/job/__init__.py index 5a1770f5..73852c24 100644 --- a/src/easyscience/job/__init__.py +++ b/src/easyscience/job/__init__.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from .analysis import AnalysisBase # noqa: F401 from .experiment import ExperimentBase # noqa: F401 diff --git a/src/easyscience/job/analysis.py b/src/easyscience/job/analysis.py index d380272a..448f1c3c 100644 --- a/src/easyscience/job/analysis.py +++ b/src/easyscience/job/analysis.py @@ -1,6 +1,6 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause + from abc import ABCMeta from abc import abstractmethod @@ -11,8 +11,8 @@ class AnalysisBase(ObjBase, metaclass=ABCMeta): - """ - This virtual class allows for the creation of technique-specific Analysis objects. + """This virtual class allows for the creation of technique-specific + Analysis objects. """ def __init__(self, name: str, interface=None, *args, **kwargs): diff --git a/src/easyscience/job/experiment.py b/src/easyscience/job/experiment.py index cc356614..0f9577c3 100644 --- a/src/easyscience/job/experiment.py +++ b/src/easyscience/job/experiment.py @@ -1,14 +1,12 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from ..base_classes.obj_base import ObjBase class ExperimentBase(ObjBase): - """ - This virtual class allows for the creation of technique-specific Experiment objects. + """This virtual class allows for the creation of technique-specific + Experiment objects. """ def __init__(self, name: str, *args, **kwargs): diff --git a/src/easyscience/job/job.py b/src/easyscience/job/job.py index 0a1df5e9..b48cbb1d 100644 --- a/src/easyscience/job/job.py +++ b/src/easyscience/job/job.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from abc import ABCMeta from abc import abstractmethod @@ -12,8 +11,8 @@ class JobBase(ObjBase, metaclass=ABCMeta): - """ - This virtual class allows for the creation of technique-specific Job objects. + """This virtual class allows for the creation of technique-specific + Job objects. """ def __init__(self, name: str, *args, **kwargs): diff --git a/src/easyscience/job/theoreticalmodel.py b/src/easyscience/job/theoreticalmodel.py index ac0fd432..609f889e 100644 --- a/src/easyscience/job/theoreticalmodel.py +++ b/src/easyscience/job/theoreticalmodel.py @@ -1,14 +1,12 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from ..base_classes.obj_base import ObjBase class TheoreticalModelBase(ObjBase): - """ - This virtual class allows for the creation of technique-specific Theory objects. + """This virtual class allows for the creation of technique-specific + Theory objects. """ def __init__(self, name: str, *args, **kwargs): diff --git a/src/easyscience/legacy/dict.py b/src/easyscience/legacy/dict.py index 9ae29397..72c57c1d 100644 --- a/src/easyscience/legacy/dict.py +++ b/src/easyscience/legacy/dict.py @@ -1,10 +1,10 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations __author__ = 'https://github.com/materialsvirtuallab/monty/blob/master/monty/json.py' __version__ = '3.0.0' -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project ComponentSerializer: class DataDictSerializer(DictSerializer): - """ - This is a serializer that can encode the data in an EasyScience object to a JSON encoded dictionary. + """This is a serializer that can encode the data in an EasyScience + object to a JSON encoded dictionary. """ def encode( @@ -75,13 +78,16 @@ def encode( full_encode: bool = False, **kwargs, ) -> Dict[str, Any]: - """ - Convert an EasyScience object to a JSON encoded data dictionary + """Convert an EasyScience object to a JSON encoded data + dictionary. :param obj: Object to be encoded. - :param skip: List of field names as strings to skip when forming the encoded object - :param full_encode: Should the data also be JSON encoded (default False) - :param kwargs: Any additional key word arguments to be passed to the encoder + :param skip: List of field names as strings to skip when forming + the encoded object + :param full_encode: Should the data also be JSON encoded + (default False) + :param kwargs: Any additional key word arguments to be passed to + the encoder :return: object encoded to data dictionary. """ @@ -96,18 +102,18 @@ def encode( @classmethod def decode(cls, d: Dict[str, Any]) -> ComponentSerializer: - """ - This function is not implemented as a data dictionary does not contain the necessary information to re-form an - EasyScience object. + """This function is not implemented as a data dictionary does + not contain the necessary information to re-form an EasyScience + object. """ - raise NotImplementedError('It is not possible to reconstitute objects from data only dictionary.') + raise NotImplementedError( + 'It is not possible to reconstitute objects from data only dictionary.' + ) @staticmethod def _parse_dict(in_dict: Dict[str, Any]) -> Dict[str, Any]: - """ - Strip out any non-data from a dictionary - """ + """Strip out any non-data from a dictionary.""" out_dict = dict() for key in in_dict.keys(): @@ -119,5 +125,8 @@ def _parse_dict(in_dict: Dict[str, Any]) -> Dict[str, Any]: if isinstance(in_dict[key], dict): out_dict[key] = DataDictSerializer._parse_dict(in_dict[key]) elif isinstance(in_dict[key], list): - out_dict[key] = [DataDictSerializer._parse_dict(x) if isinstance(x, dict) else x for x in in_dict[key]] + out_dict[key] = [ + DataDictSerializer._parse_dict(x) if isinstance(x, dict) else x + for x in in_dict[key] + ] return out_dict diff --git a/src/easyscience/legacy/json.py b/src/easyscience/legacy/json.py index 6464e52a..12a151e7 100644 --- a/src/easyscience/legacy/json.py +++ b/src/easyscience/legacy/json.py @@ -1,12 +1,11 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations __author__ = 'https://github.com/materialsvirtuallab/monty/blob/master/monty/json.py' __version__ = '3.0.0' -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project str: - """ - Returns a json string representation of the ComponentSerializer object. + """Returns a json string representation of the + ComponentSerializer object. """ ENCODER = type( JsonEncoderTemplate.__name__, @@ -37,8 +36,8 @@ def decode(cls, data: str) -> ComponentSerializer: class JsonDataSerializer(BaseEncoderDecoder): def encode(self, obj: ComponentSerializer, skip: List[str] = []) -> str: - """ - Returns a json string representation of the ComponentSerializer object. + """Returns a json string representation of the + ComponentSerializer object. """ from .dict import DataDictSerializer @@ -57,13 +56,15 @@ def encode(self, obj: ComponentSerializer, skip: List[str] = []) -> str: @classmethod def decode(cls, data: str) -> ComponentSerializer: - raise NotImplementedError('It is not possible to reconstitute objects from data only objects.') + raise NotImplementedError( + 'It is not possible to reconstitute objects from data only objects.' + ) class JsonEncoderTemplate(json.JSONEncoder): - """ - A Json Encoder which supports the ComponentSerializer API, plus adds support for - numpy arrays, datetime objects, bson ObjectIds (requires bson). + """A Json Encoder which supports the ComponentSerializer API, plus + adds support for numpy arrays, datetime objects, bson ObjectIds + (requires bson). Usage:: @@ -92,13 +93,12 @@ def default(self, o) -> dict: # pylint: disable=E0202 class JsonDecoderTemplate(json.JSONDecoder): - """ - A Json Decoder which supports the ComponentSerializer API. By default, the - decoder attempts to find a module and name associated with a dict. If - found, the decoder will generate a Pymatgen as a priority. If that fails, - the original decoded dictionary from the string is returned. Note that - nested lists and dicts containing pymatgen object will be decoded correctly - as well. + """A Json Decoder which supports the ComponentSerializer API. By + default, the decoder attempts to find a module and name associated + with a dict. If found, the decoder will generate a Pymatgen as a + priority. If that fails, the original decoded dictionary from the + string is returned. Note that nested lists and dicts containing + pymatgen object will be decoded correctly as well. Usage: @@ -109,8 +109,7 @@ class JsonDecoderTemplate(json.JSONDecoder): _converter = BaseEncoderDecoder._convert_from_dict def decode(self, s): - """ - Overrides decode from JSONDecoder. + """Overrides decode from JSONDecoder. :param s: string :return: Object. diff --git a/src/easyscience/legacy/legacy_core.py b/src/easyscience/legacy/legacy_core.py index daddabee..1fed4b86 100644 --- a/src/easyscience/legacy/legacy_core.py +++ b/src/easyscience/legacy/legacy_core.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from __future__ import annotations @@ -22,9 +21,12 @@ class ComponentSerializer: - """ - This is the base class for all EasyScience objects and deals with the data conversion to other formats via the `encode` - and `decode` functions. Shortcuts for dictionary and data dictionary encoding is also present. + """This is the base class for all EasyScience objects and deals with + the data conversion to other formats via the `encode` and `decode` + functions. + + Shortcuts for dictionary and data dictionary encoding is also + present. """ _CORE = True @@ -32,9 +34,14 @@ class ComponentSerializer: def __deepcopy__(self, memo): return self.from_dict(self.as_dict()) - def encode(self, skip: Optional[List[str]] = None, encoder: Optional[BaseEncoderDecoder] = None, **kwargs) -> Any: - """ - Use an encoder to covert an EasyScience object into another format. Default is to a dictionary using `DictSerializer`. + def encode( + self, + skip: Optional[List[str]] = None, + encoder: Optional[BaseEncoderDecoder] = None, + **kwargs, + ) -> Any: + """Use an encoder to covert an EasyScience object into another + format. Default is to a dictionary using `DictSerializer`. :param skip: List of field names as strings to skip when forming the encoded object :param encoder: The encoder to be used for encoding the data. Default is `DictSerializer` @@ -48,11 +55,12 @@ def encode(self, skip: Optional[List[str]] = None, encoder: Optional[BaseEncoder @classmethod def decode(cls, obj: Any, decoder: Optional[BaseEncoderDecoder] = None) -> Any: - """ - Re-create an EasyScience object from the output of an encoder. The default decoder is `DictSerializer`. + """Re-create an EasyScience object from the output of an + encoder. The default decoder is `DictSerializer`. :param obj: encoded EasyScience object - :param decoder: decoder to be used to reform the EasyScience object + :param decoder: decoder to be used to reform the EasyScience + object :return: Reformed EasyScience object """ @@ -61,20 +69,22 @@ def decode(cls, obj: Any, decoder: Optional[BaseEncoderDecoder] = None) -> Any: return decoder.decode(obj) def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: - """ - Convert an EasyScience object into a full dictionary using `DictSerializer`. - This is a shortcut for ```obj.encode(encoder=DictSerializer)``` - - :param skip: List of field names as strings to skip when forming the dictionary - :return: encoded object containing all information to reform an EasyScience object. + """Convert an EasyScience object into a full dictionary using + `DictSerializer`. This is a shortcut for + ```obj.encode(encoder=DictSerializer)``` + + :param skip: List of field names as strings to skip when forming + the dictionary + :return: encoded object containing all information to reform an + EasyScience object. """ return self.encode(skip=skip, encoder=DictSerializer) @classmethod def from_dict(cls, obj_dict: Dict[str, Any]) -> None: - """ - Re-create an EasyScience object from a full encoded dictionary. + """Re-create an EasyScience object from a full encoded + dictionary. :param obj_dict: dictionary containing the serialized contents (from `DictSerializer`) of an EasyScience object :return: Reformed EasyScience object @@ -82,9 +92,14 @@ def from_dict(cls, obj_dict: Dict[str, Any]) -> None: return cls.decode(obj_dict, decoder=DictSerializer) - def encode_data(self, skip: Optional[List[str]] = None, encoder: Optional[BaseEncoderDecoder] = None, **kwargs) -> Any: - """ - Returns just the data in an EasyScience object win the format specified by an encoder. + def encode_data( + self, + skip: Optional[List[str]] = None, + encoder: Optional[BaseEncoderDecoder] = None, + **kwargs, + ) -> Any: + """Returns just the data in an EasyScience object win the format + specified by an encoder. :param skip: List of field names as strings to skip when forming the dictionary :param encoder: The encoder to be used for encoding the data. Default is `DataDictSerializer` @@ -97,20 +112,23 @@ def encode_data(self, skip: Optional[List[str]] = None, encoder: Optional[BaseEn return self.encode(skip=skip, encoder=encoder, **kwargs) def as_data_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: - """ - Returns a dictionary containing just the data of an EasyScience object. + """Returns a dictionary containing just the data of an + EasyScience object. - :param skip: List of field names as strings to skip when forming the dictionary - :return: dictionary containing just the data of an EasyScience object. + :param skip: List of field names as strings to skip when forming + the dictionary + :return: dictionary containing just the data of an EasyScience + object. """ return self.encode(skip=skip, encoder=DataDictSerializer) def unsafe_hash(self) -> sha1: - """ - Returns an hash of the current object. This uses a generic but low - performance method of converting the object to a dictionary, flattening - any nested keys, and then performing a hash on the resulting object + """Returns an hash of the current object. + + This uses a generic but low performance method of converting the + object to a dictionary, flattening any nested keys, and then + performing a hash on the resulting object """ def flatten(obj, seperator='.'): @@ -119,9 +137,15 @@ def flatten(obj, seperator='.'): flat_dict = {} for key, value in obj.items(): if isinstance(value, dict): - flat_dict.update({seperator.join([key, _key]): _value for _key, _value in flatten(value).items()}) + flat_dict.update({ + seperator.join([key, _key]): _value + for _key, _value in flatten(value).items() + }) elif isinstance(value, list): - list_dict = {'{}{}{}'.format(key, seperator, num): item for num, item in enumerate(value)} + list_dict = { + '{}{}{}'.format(key, seperator, num): item + for num, item in enumerate(value) + } flat_dict.update(flatten(list_dict)) else: flat_dict[key] = value diff --git a/src/easyscience/legacy/xml.py b/src/easyscience/legacy/xml.py index e0898409..7ec29950 100644 --- a/src/easyscience/legacy/xml.py +++ b/src/easyscience/legacy/xml.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from __future__ import annotations @@ -26,8 +25,8 @@ class XMLSerializer(BaseEncoderDecoder): - """ - This is a serializer that can encode and decode EasyScience objects to a basic xml format. + """This is a serializer that can encode and decode EasyScience + objects to a basic xml format. """ def encode( @@ -39,16 +38,20 @@ def encode( use_header: bool = False, **kwargs, ) -> str: - """ - Convert an EasyScience object to an XML encoded string. Note that for speed the `fast` setting can be changed to - `True`. An XML document with initial block *data* is returned. + """Convert an EasyScience object to an XML encoded string. Note + that for speed the `fast` setting can be changed to `True`. An + XML document with initial block *data* is returned. :param obj: Object to be encoded. - :param skip: List of field names as strings to skip when forming the encoded object + :param skip: List of field names as strings to skip when forming + the encoded object :param data_only: Should only the object's data be encoded. - :param fast: Should the returned string be pretty? This can be turned off for speed. - :param use_header: Should a header of `'?xml version="1.0" encoding="UTF-8"?'` be included? - :param kwargs: Any additional key-words to pass to the Dictionary Serializer. + :param fast: Should the returned string be pretty? This can be + turned off for speed. + :param use_header: Should a header of `'?xml version="1.0" + encoding="UTF-8"?'` be included? + :param kwargs: Any additional key-words to pass to the + Dictionary Serializer. :return: string containing the XML encoded object """ @@ -74,8 +77,8 @@ def encode( @classmethod def decode(cls, data: str) -> ComponentSerializer: - """ - Decode an EasyScience object which has been encoded in XML format. + """Decode an EasyScience object which has been encoded in XML + format. :param data: String containing XML encoded data. :return: Reformed EasyScience object. @@ -89,9 +92,7 @@ def decode(cls, data: str) -> ComponentSerializer: @staticmethod def _element_to_dict(element, out_dict): - """ - Convert an XML element to a dictionary recursively. - """ + """Convert an XML element to a dictionary recursively.""" label = element.tag if label[0] == '_': @@ -113,9 +114,7 @@ def _element_to_dict(element, out_dict): @staticmethod def string_to_variable(in_string: str): - """ - Convert an XML encoded string to JSON form. - """ + """Convert an XML encoded string to JSON form.""" if in_string is None: return in_string in_string = in_string.strip() @@ -137,8 +136,8 @@ def string_to_variable(in_string: str): return value def _check_class(self, element, key: str, value: Any, skip: Optional[List[str]] = None): - """ - Add a value to an element or create a new element based on input type. + """Add a value to an element or create a new element based on + input type. """ T_ = type(value) if isinstance(value, dict): diff --git a/src/easyscience/models/__init__.py b/src/easyscience/models/__init__.py index a9aed973..3fc7f778 100644 --- a/src/easyscience/models/__init__.py +++ b/src/easyscience/models/__init__.py @@ -1,5 +1,4 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from .polynomial import Polynomial # noqa: F401 diff --git a/src/easyscience/models/polynomial.py b/src/easyscience/models/polynomial.py index 9ea2576e..5cc4170b 100644 --- a/src/easyscience/models/polynomial.py +++ b/src/easyscience/models/polynomial.py @@ -1,7 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from typing import ClassVar from typing import Iterable @@ -16,8 +14,7 @@ class Polynomial(ObjBase): - """ - A polynomial model. + """A polynomial model. Parameters ---------- @@ -59,7 +56,11 @@ def __repr__(self): if len(self.coefficients) >= 2: s += [f'{self.coefficients[1].value}x'] if len(self.coefficients) >= 3: - s += [f'{c.value}x^{i + 2}' for i, c in enumerate(self.coefficients[2:]) if c.value != 0] + s += [ + f'{c.value}x^{i + 2}' + for i, c in enumerate(self.coefficients[2:]) + if c.value != 0 + ] s.reverse() s = ' + '.join(s) return 'Polynomial({}, {})'.format(self.name, s) diff --git a/src/easyscience/utils/__init__.py b/src/easyscience/utils/__init__.py index 462d95af..554dc85e 100644 --- a/src/easyscience/utils/__init__.py +++ b/src/easyscience/utils/__init__.py @@ -1,3 +1,3 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause + diff --git a/src/easyscience/utils/classTools.py b/src/easyscience/utils/classTools.py index 6b2b9555..151f36c1 100644 --- a/src/easyscience/utils/classTools.py +++ b/src/easyscience/utils/classTools.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from __future__ import annotations diff --git a/src/easyscience/utils/classUtils.py b/src/easyscience/utils/classUtils.py index fd08c343..6d56028a 100644 --- a/src/easyscience/utils/classUtils.py +++ b/src/easyscience/utils/classUtils.py @@ -1,19 +1,16 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from functools import wraps def singleton(cls): - """ - This decorator can be used to create a singleton out of a class. + """This decorator can be used to create a singleton out of a class. Usage:: @singleton - class MySingleton(): - + class MySingleton: def __init__(): pass """ @@ -29,10 +26,9 @@ def get_instance(): def cached_class(klass): - """ - Decorator to cache class instances by constructor arguments. - This results in a class that behaves like a singleton for each - set of constructor arguments, ensuring efficiency. + """Decorator to cache class instances by constructor arguments. This + results in a class that behaves like a singleton for each set of + constructor arguments, ensuring efficiency. Note that this should be used for *immutable classes only*. Having a cached mutable class makes very little sense. For efficiency, @@ -40,10 +36,9 @@ def cached_class(klass): constructor arguments permutations. The keywords argument dictionary is converted to a tuple because - dicts are mutable; keywords themselves are strings and - so are always hashable, but if any arguments (keyword - or positional) are non-hashable, that set of arguments - is not cached. + dicts are mutable; keywords themselves are strings and so are always + hashable, but if any arguments (keyword or positional) are non- + hashable, that set of arguments is not cached. """ cache = {} @@ -54,8 +49,8 @@ class _decorated(klass): __doc__ = klass.__doc__ def __new__(cls, *args, **kwargs): - """ - Pass through... + """Pass through... + :param args: :param kwargs: :return: diff --git a/src/easyscience/utils/decorators.py b/src/easyscience/utils/decorators.py index 057bb815..16457b48 100644 --- a/src/easyscience/utils/decorators.py +++ b/src/easyscience/utils/decorators.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause import collections.abc import functools @@ -11,10 +10,11 @@ class memoized: - """ - Decorator. Caches a function's return value each time it is called. - If called later with the same arguments, the cached value is returned - (not reevaluated). + """Decorator. + + Caches a function's return value each time it is called. If called + later with the same arguments, the cached value is returned (not + reevaluated). """ def __init__(self, func): @@ -42,10 +42,9 @@ def __get__(self, obj, objtype): def counted(func): - """ - Counts how many times a function has been called and adds a `func.calls` to it's properties - :param func: Function to be counted - :return: Results from function call + """Counts how many times a function has been called and adds a + `func.calls` to it's properties :param func: Function to be counted + :return: Results from function call. """ @functools.wraps(func) @@ -58,10 +57,9 @@ def wrapped(*args, **kwargs): def time_it(func): - """ - Times a function and reports the time either to the class' log or the base logger - :param func: function to be timed - :return: callable function with timer + """Times a function and reports the time either to the class' log or + the base logger :param func: function to be timed :return: callable + function with timer. """ name = func.__module__ + '.' + func.__name__ time_logger = global_object.log.getLogger('timer.' + name) @@ -79,10 +77,10 @@ def _time_it(*args, **kwargs): def deprecated(func): - """ - This is a decorator which can be used to mark functions - as deprecated. It will result in a warning being emitted - when the function is used. + """This is a decorator which can be used to mark functions as + deprecated. + + It will result in a warning being emitted when the function is used. """ @functools.wraps(func) diff --git a/src/easyscience/utils/string.py b/src/easyscience/utils/string.py index 23f344e6..e8a2456d 100644 --- a/src/easyscience/utils/string.py +++ b/src/easyscience/utils/string.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from fractions import Fraction @@ -9,11 +8,13 @@ """ -def transformation_to_string(matrix, translation_vec=(0, 0, 0), components=('x', 'y', 'z'), c='', delim=','): - """ - Convenience method. Given matrix returns string, e.g. x+2y+1/4 - :param matrix - :param translation_vec +def transformation_to_string( + matrix, translation_vec=(0, 0, 0), components=('x', 'y', 'z'), c='', delim=',' +): + """Convenience method. + + Given matrix returns string, e.g. x+2y+1/4 + :param matrix : param translation_vec :param components: either ('x', 'y', 'z') or ('a', 'b', 'c') :param c: optional additional character to print (used for magmoms) :param delim: delimiter diff --git a/src/easyscience/variable/__init__.py b/src/easyscience/variable/__init__.py index 96094cab..121d5cf9 100644 --- a/src/easyscience/variable/__init__.py +++ b/src/easyscience/variable/__init__.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from .descriptor_any_type import DescriptorAnyType from .descriptor_array import DescriptorArray from .descriptor_base import DescriptorBase diff --git a/src/easyscience/variable/descriptor_any_type.py b/src/easyscience/variable/descriptor_any_type.py index c00ccb01..6bdf7f39 100644 --- a/src/easyscience/variable/descriptor_any_type.py +++ b/src/easyscience/variable/descriptor_any_type.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations import numbers @@ -15,9 +18,11 @@ class DescriptorAnyType(DescriptorBase): - """ - A `Descriptor` for any type that does not fit the other Descriptors. Should be avoided when possible. - It was created to hold the symmetry operations used in the SpaceGroup class of EasyCrystallography. + """A `Descriptor` for any type that does not fit the other + Descriptors. + + Should be avoided when possible. It was created to hold the symmetry + operations used in the SpaceGroup class of EasyCrystallography. """ def __init__( @@ -30,7 +35,7 @@ def __init__( display_name: Optional[str] = None, parent: Optional[Any] = None, ): - """Constructor for the DescriptorAnyType class + """Constructor for the DescriptorAnyType class. param name: Name of the descriptor param value: Value of the descriptor @@ -54,8 +59,7 @@ def __init__( @property def value(self) -> numbers.Number: - """ - Get the value. + """Get the value. :return: Value of self. """ @@ -64,8 +68,7 @@ def value(self) -> numbers.Number: @value.setter @property_stack def value(self, value: Union[list, np.ndarray]) -> None: - """ - Set the value of self. + """Set the value of self. :param value: New value for the DescriptorAnyType. """ @@ -75,8 +78,8 @@ def __copy__(self) -> DescriptorAnyType: return super().__copy__() def __repr__(self) -> str: - """ - Return a string representation of the DescriptorAnyType, showing its name and value. + """Return a string representation of the DescriptorAnyType, + showing its name and value. """ if hasattr(self._value, '__repr__'): diff --git a/src/easyscience/variable/descriptor_array.py b/src/easyscience/variable/descriptor_array.py index 9e9b8e6f..aecc684a 100644 --- a/src/easyscience/variable/descriptor_array.py +++ b/src/easyscience/variable/descriptor_array.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations import numbers @@ -23,8 +26,9 @@ class DescriptorArray(DescriptorBase): - """ - A `Descriptor` for Array values with units. The internal representation is a scipp array. + """A `Descriptor` for Array values with units. + + The internal representation is a scipp array. """ def __init__( @@ -40,7 +44,7 @@ def __init__( parent: Optional[Any] = None, dimensions: Optional[list] = None, ): - """Constructor for the DescriptorArray class + """Constructor for the DescriptorArray class. param name: Name of the descriptor param value: List containing the values of the descriptor @@ -72,13 +76,17 @@ def __init__( variance = np.astype(variance, 'float') if not isinstance(unit, sc.Unit) and not isinstance(unit, str): - raise TypeError(f'{unit=} must be a scipp unit or a string representing a valid scipp unit') + raise TypeError( + f'{unit=} must be a scipp unit or a string representing a valid scipp unit' + ) if dimensions is None: # Autogenerate dimensions if not supplied dimensions = ['dim' + str(i) for i in range(len(value.shape))] if not len(dimensions) == len(value.shape): - raise ValueError(f'Length of dimensions ({dimensions=}) does not match length of value {value=}.') + raise ValueError( + f'Length of dimensions ({dimensions=}) does not match length of value {value=}.' + ) self._dimensions = dimensions try: @@ -104,8 +112,7 @@ def __init__( @classmethod def from_scipp(cls, name: str, full_value: Variable, **kwargs) -> DescriptorArray: - """ - Create a DescriptorArray from a scipp array. + """Create a DescriptorArray from a scipp array. :param name: Name of the descriptor :param full_value: Value of the descriptor as a scipp variable @@ -125,8 +132,8 @@ def from_scipp(cls, name: str, full_value: Variable, **kwargs) -> DescriptorArra @property def full_value(self) -> Variable: - """ - Get the value of self as a scipp array. This should be usable for most cases. + """Get the value of self as a scipp array. This should be usable + for most cases. :return: Value of self with unit. """ @@ -140,8 +147,8 @@ def full_value(self, full_value: Variable) -> None: @property def value(self) -> numbers.Number: - """ - Get the value without units. The Scipp array can be obtained from `obj.full_value`. + """Get the value without units. The Scipp array can be obtained + from `obj.full_value`. :return: Value of self without unit. """ @@ -150,11 +157,12 @@ def value(self) -> numbers.Number: @value.setter @property_stack def value(self, value: Union[list, np.ndarray]) -> None: - """ - Set the value of self. Ensures the input is an array and matches the shape of the existing array. - The full value can be obtained from `obj.full_value`. + """Set the value of self. Ensures the input is an array and + matches the shape of the existing array. The full value can be + obtained from `obj.full_value`. - :param value: New value for the DescriptorArray, must be a list or numpy array. + :param value: New value for the DescriptorArray, must be a list + or numpy array. """ if not isinstance(value, (list, np.ndarray)): raise TypeError(f'{value=} must be a list or numpy array.') @@ -169,8 +177,7 @@ def value(self, value: Union[list, np.ndarray]) -> None: @property def dimensions(self) -> list: - """ - Get the dimensions used for the underlying scipp array. + """Get the dimensions used for the underlying scipp array. :return: dimensions of self. """ @@ -178,8 +185,8 @@ def dimensions(self) -> list: @dimensions.setter def dimensions(self, dimensions: Union[list]) -> None: - """ - Set the dimensions of self. Ensures that the input has a shape compatible with self.full_value. + """Set the dimensions of self. Ensures that the input has a + shape compatible with self.full_value. :param value: list of dimensions. """ @@ -191,14 +198,15 @@ def dimensions(self, dimensions: Union[list]) -> None: self._dimensions = dimensions # Also rename the dims of the scipp array - rename_dict = {old_dim: new_dim for (old_dim, new_dim) in zip(self.full_value.dims, dimensions)} + rename_dict = { + old_dim: new_dim for (old_dim, new_dim) in zip(self.full_value.dims, dimensions) + } renamed_array = self._array.rename_dims(rename_dict) self._array = renamed_array @property def unit(self) -> str: - """ - Get the unit. + """Get the unit. :return: Unit as a string. """ @@ -215,8 +223,7 @@ def unit(self, unit_str: str) -> None: @property def variance(self) -> np.ndarray: - """ - Get the variance as a Numpy ndarray. + """Get the variance as a Numpy ndarray. :return: variance. """ @@ -225,16 +232,19 @@ def variance(self) -> np.ndarray: @variance.setter @property_stack def variance(self, variance: Union[list, np.ndarray]) -> None: - """ - Set the variance of self. Ensures the input is an array and matches the shape of the existing values. + """Set the variance of self. Ensures the input is an array and + matches the shape of the existing values. - :param variance: New variance for the DescriptorArray, must be a list or numpy array. + :param variance: New variance for the DescriptorArray, must be a + list or numpy array. """ if variance is not None: if not isinstance(variance, (list, np.ndarray)): raise TypeError(f'{variance=} must be a list or numpy array.') if isinstance(variance, list): - variance = np.array(variance) # Convert lists to numpy arrays for consistent handling. + variance = np.array( + variance + ) # Convert lists to numpy arrays for consistent handling. if variance.shape != self._array.shape: raise ValueError(f'{variance=} must have the same shape as the array values.') @@ -247,10 +257,11 @@ def variance(self, variance: Union[list, np.ndarray]) -> None: @property def error(self) -> Optional[np.ndarray]: - """ - The standard deviations, calculated as the square root of variances. + """The standard deviations, calculated as the square root of + variances. - :return: A numpy array of standard deviations, or None if variances are not set. + :return: A numpy array of standard deviations, or None if + variances are not set. """ if self._array.variances is None: return None @@ -259,8 +270,8 @@ def error(self) -> Optional[np.ndarray]: @error.setter @property_stack def error(self, error: Union[list, np.ndarray]) -> None: - """ - Set the standard deviation for the parameter, which updates the variances. + """Set the standard deviation for the parameter, which updates + the variances. :param error: A list or numpy array of standard deviations. """ @@ -282,8 +293,7 @@ def error(self, error: Union[list, np.ndarray]) -> None: self._array.variances = None def convert_unit(self, unit_str: str) -> None: - """ - Convert the value from one unit system to another. + """Convert the value from one unit system to another. :param unit_str: New unit in string form """ @@ -306,21 +316,22 @@ def set_array(obj, scalar): # Push to undo stack self._global_object.stack.push( - PropertyStack(self, set_array, old_array, new_array, text=f'Convert unit to {unit_str}') + PropertyStack( + self, set_array, old_array, new_array, text=f'Convert unit to {unit_str}' + ) ) # Update the array self._array = new_array def __copy__(self) -> DescriptorArray: - """ - Return a copy of the current DescriptorArray. - """ + """Return a copy of the current DescriptorArray.""" return super().__copy__() def __repr__(self) -> str: - """ - Return a string representation of the DescriptorArray, showing its name, value, variance, and unit. + """Return a string representation of the DescriptorArray, + showing its name, value, variance, and unit. + Large arrays are summarized for brevity. """ # Base string with name @@ -355,9 +366,10 @@ def __repr__(self) -> str: return string def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: - """ - Dict representation of the current DescriptorArray. The dict contains the value, unit and variances, - in addition to the properties of DescriptorBase. + """Dict representation of the current DescriptorArray. + + The dict contains the value, unit and variances, in addition to + the properties of DescriptorBase. """ raw_dict = super().as_dict(skip=skip) raw_dict['value'] = self._array.values @@ -372,13 +384,16 @@ def _apply_operation( operation: Callable, units_must_match: bool = True, ) -> DescriptorArray: - """ - Perform element-wise operations with another DescriptorNumber, DescriptorArray, list, or number. + """Perform element-wise operations with another + DescriptorNumber, DescriptorArray, list, or number. - :param other: The object to operate on. Must be a DescriptorArray or DescriptorNumber with compatible units, - or a list with the same shape if the DescriptorArray is dimensionless. + :param other: The object to operate on. Must be a + DescriptorArray or DescriptorNumber with compatible units, + or a list with the same shape if the DescriptorArray is + dimensionless. :param operation: The operation to perform - :return: A new DescriptorArray representing the result of the operation. + :return: A new DescriptorArray representing the result of the + operation. """ if isinstance(other, numbers.Number): # Does not need to be dimensionless for multiplication and division @@ -392,10 +407,14 @@ def _apply_operation( # Ensure dimensions match if np.shape(other) != self._array.values.shape: - raise ValueError(f'Shape of {other=} must match the shape of DescriptorArray values') + raise ValueError( + f'Shape of {other=} must match the shape of DescriptorArray values' + ) other = sc.array(dims=self._array.dims, values=other) - new_full_value = operation(self._array, other) # Let scipp handle operation for uncertainty propagation + new_full_value = operation( + self._array, other + ) # Let scipp handle operation for uncertainty propagation elif isinstance(other, DescriptorNumber): try: @@ -403,7 +422,9 @@ def _apply_operation( other_converted.convert_unit(self.unit) except UnitError: if units_must_match: - raise UnitError(f'Values with units {self.unit} and {other.unit} are not compatible') from None + raise UnitError( + f'Values with units {self.unit} and {other.unit} are not compatible' + ) from None # Operations with a DescriptorNumber that has a variance WILL introduce # correlations between the elements of the DescriptorArray. # See, https://content.iospress.com/articles/journal-of-neutron-research/jnr220049 @@ -418,7 +439,9 @@ def _apply_operation( UserWarning, ) # Cheeky copy() of broadcasted scipp array to force scipp to perform the broadcast here - broadcasted = sc.broadcast(other_converted.full_value, dims=self._array.dims, shape=self._array.shape).copy() + broadcasted = sc.broadcast( + other_converted.full_value, dims=self._array.dims, shape=self._array.shape + ).copy() new_full_value = operation(self.full_value, broadcasted) elif isinstance(other, DescriptorArray): @@ -427,7 +450,9 @@ def _apply_operation( other_converted.convert_unit(self.unit) except UnitError: if units_must_match: - raise UnitError(f'Values with units {self.unit} and {other.unit} are incompatible') from None + raise UnitError( + f'Values with units {self.unit} and {other.unit} are incompatible' + ) from None # Ensure dimensions match if self.full_value.dims != other_converted.full_value.dims: @@ -451,8 +476,9 @@ def _rapply_operation( operation: Callable, units_must_match: bool = True, ) -> DescriptorArray: - """ - Handle reverse operations for DescriptorArrays, DescriptorNumbers, lists, and scalars. + """Handle reverse operations for DescriptorArrays, + DescriptorNumbers, lists, and scalars. + Ensures unit compatibility when `other` is a DescriptorNumber. """ @@ -470,7 +496,9 @@ def reversed_operation(a, b): # the units for mul/div, but if the conversion # fails it's no big deal. if units_must_match: - raise UnitError(f'Values with units {self.unit} and {other.unit} are incompatible') from None + raise UnitError( + f'Values with units {self.unit} and {other.unit} are incompatible' + ) from None result = self._apply_operation(other, reversed_operation, units_must_match) # Revert `self` to its original unit self.convert_unit(original_unit) @@ -480,45 +508,59 @@ def reversed_operation(a, b): return self._apply_operation(other, reversed_operation, units_must_match) def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): - """ - DescriptorArray does not generally support Numpy array functions. - For example, `np.argwhere(descriptorArray: DescriptorArray)` should fail. - Modify this function if you want to add such functionality. + """DescriptorArray does not generally support Numpy array + functions. + + For example, `np.argwhere(descriptorArray: DescriptorArray)` + should fail. Modify this function if you want to add such + functionality. """ return NotImplemented def __array_function__(self, func, types, args, kwargs): - """ - DescriptorArray does not generally support Numpy array functions. - For example, `np.argwhere(descriptorArray: DescriptorArray)` should fail. - Modify this function if you want to add such functionality. + """DescriptorArray does not generally support Numpy array + functions. + + For example, `np.argwhere(descriptorArray: DescriptorArray)` + should fail. Modify this function if you want to add such + functionality. """ return NotImplemented - def __add__(self, other: Union[DescriptorArray, DescriptorNumber, list, numbers.Number]) -> DescriptorArray: - """ - Perform element-wise addition with another DescriptorNumber, DescriptorArray, list, or number. + def __add__( + self, other: Union[DescriptorArray, DescriptorNumber, list, numbers.Number] + ) -> DescriptorArray: + """Perform element-wise addition with another DescriptorNumber, + DescriptorArray, list, or number. - :param other: The object to add. Must be a DescriptorArray or DescriptorNumber with compatible units, - or a list with the same shape if the DescriptorArray is dimensionless, or a number. - :return: A new DescriptorArray representing the result of the addition. + :param other: The object to add. Must be a DescriptorArray or + DescriptorNumber with compatible units, or a list with the + same shape if the DescriptorArray is dimensionless, or a + number. + :return: A new DescriptorArray representing the result of the + addition. """ return self._apply_operation(other, operator.add) def __radd__(self, other: Union[DescriptorNumber, list, numbers.Number]) -> DescriptorArray: - """ - Handle reverse addition for DescriptorArrays, DescriptorNumbers, lists, and scalars. + """Handle reverse addition for DescriptorArrays, + DescriptorNumbers, lists, and scalars. + Ensures unit compatibility when `other` is a DescriptorNumber. """ return self._rapply_operation(other, operator.add) - def __sub__(self, other: Union[DescriptorArray, list, np.ndarray, numbers.Number]) -> DescriptorArray: - """ - Perform element-wise subtraction with another DescriptorArray, list, or number. + def __sub__( + self, other: Union[DescriptorArray, list, np.ndarray, numbers.Number] + ) -> DescriptorArray: + """Perform element-wise subtraction with another + DescriptorArray, list, or number. - :param other: The object to subtract. Must be a DescriptorArray with compatible units, - or a list with the same shape if the DescriptorArray is dimensionless. - :return: A new DescriptorArray representing the result of the subtraction. + :param other: The object to subtract. Must be a DescriptorArray + with compatible units, or a list with the same shape if the + DescriptorArray is dimensionless. + :return: A new DescriptorArray representing the result of the + subtraction. """ if isinstance(other, (DescriptorArray, DescriptorNumber, list, numbers.Number)): # Leverage __neg__ and __add__ for subtraction @@ -532,12 +574,14 @@ def __sub__(self, other: Union[DescriptorArray, list, np.ndarray, numbers.Number return NotImplemented def __rsub__(self, other: Union[DescriptorNumber, list, numbers.Number]) -> DescriptorArray: - """ - Perform element-wise subtraction with another DescriptorNumber, list, or number. + """Perform element-wise subtraction with another + DescriptorNumber, list, or number. - :param other: The object to subtract. Must be a DescriptorArray with compatible units, - or a list with the same shape if the DescriptorArray is dimensionless. - :return: A new DescriptorArray representing the result of the subtraction. + :param other: The object to subtract. Must be a DescriptorArray + with compatible units, or a list with the same shape if the + DescriptorArray is dimensionless. + :return: A new DescriptorArray representing the result of the + subtraction. """ if isinstance(other, (DescriptorNumber, list, numbers.Number)): if isinstance(other, list): @@ -549,34 +593,44 @@ def __rsub__(self, other: Union[DescriptorNumber, list, numbers.Number]) -> Desc else: return NotImplemented - def __mul__(self, other: Union[DescriptorArray, DescriptorNumber, list, numbers.Number]) -> DescriptorArray: - """ - Perform element-wise multiplication with another DescriptorNumber, DescriptorArray, list, or number. + def __mul__( + self, other: Union[DescriptorArray, DescriptorNumber, list, numbers.Number] + ) -> DescriptorArray: + """Perform element-wise multiplication with another + DescriptorNumber, DescriptorArray, list, or number. - :param other: The object to multiply. Must be a DescriptorArray or DescriptorNumber with compatible units, - or a list with the same shape if the DescriptorArray is dimensionless. - :return: A new DescriptorArray representing the result of the addition. + :param other: The object to multiply. Must be a DescriptorArray + or DescriptorNumber with compatible units, or a list with + the same shape if the DescriptorArray is dimensionless. + :return: A new DescriptorArray representing the result of the + addition. """ if not isinstance(other, (DescriptorArray, DescriptorNumber, list, numbers.Number)): return NotImplemented return self._apply_operation(other, operator.mul, units_must_match=False) def __rmul__(self, other: Union[DescriptorNumber, list, numbers.Number]) -> DescriptorArray: - """ - Handle reverse multiplication for DescriptorNumbers, lists, and scalars. + """Handle reverse multiplication for DescriptorNumbers, lists, + and scalars. + Ensures unit compatibility when `other` is a DescriptorNumber. """ if not isinstance(other, (DescriptorNumber, list, numbers.Number)): return NotImplemented return self._rapply_operation(other, operator.mul, units_must_match=False) - def __truediv__(self, other: Union[DescriptorArray, DescriptorNumber, list, numbers.Number]) -> DescriptorArray: - """ - Perform element-wise division with another DescriptorNumber, DescriptorArray, list, or number. + def __truediv__( + self, other: Union[DescriptorArray, DescriptorNumber, list, numbers.Number] + ) -> DescriptorArray: + """Perform element-wise division with another DescriptorNumber, + DescriptorArray, list, or number. - :param other: The object to use as a denominator. Must be a DescriptorArray or DescriptorNumber with compatible units, - or a list with the same shape if the DescriptorArray is dimensionless. - :return: A new DescriptorArray representing the result of the addition. + :param other: The object to use as a denominator. Must be a + DescriptorArray or DescriptorNumber with compatible units, + or a list with the same shape if the DescriptorArray is + dimensionless. + :return: A new DescriptorArray representing the result of the + addition. """ if not isinstance(other, (DescriptorArray, DescriptorNumber, list, numbers.Number)): return NotImplemented @@ -592,9 +646,12 @@ def __truediv__(self, other: Union[DescriptorArray, DescriptorNumber, list, numb raise ZeroDivisionError('Cannot divide by zero') return self._apply_operation(other, operator.truediv, units_must_match=False) - def __rtruediv__(self, other: Union[DescriptorNumber, list, numbers.Number]) -> DescriptorArray: - """ - Handle reverse division for DescriptorNumbers, lists, and scalars. + def __rtruediv__( + self, other: Union[DescriptorNumber, list, numbers.Number] + ) -> DescriptorArray: + """Handle reverse division for DescriptorNumbers, lists, and + scalars. + Ensures unit compatibility when `other` is a DescriptorNumber. """ if not isinstance(other, (DescriptorNumber, list, numbers.Number)): @@ -609,12 +666,13 @@ def __rtruediv__(self, other: Union[DescriptorNumber, list, numbers.Number]) -> return inverse_result def __pow__(self, other: Union[DescriptorNumber, numbers.Number]) -> DescriptorArray: - """ - Perform element-wise exponentiation with another DescriptorNumber or number. + """Perform element-wise exponentiation with another + DescriptorNumber or number. - :param other: The object to use as a denominator. Must be a number or DescriptorNumber with - no unit or variance. - :return: A new DescriptorArray representing the result of the addition. + :param other: The object to use as a denominator. Must be a + number or DescriptorNumber with no unit or variance. + :return: A new DescriptorArray representing the result of the + addition. """ if not isinstance(other, (numbers.Number, DescriptorNumber)): return NotImplemented @@ -640,27 +698,26 @@ def __pow__(self, other: Union[DescriptorNumber, numbers.Number]) -> DescriptorA return descriptor_number def __rpow__(self, other: numbers.Number): - """ - Defers reverse pow with a descriptor array, `a ** array`. - Exponentiation with regards to an array does not make sense, - and is not implemented. + """Defers reverse pow with a descriptor array, `a ** array`. + + Exponentiation with regards to an array does not make sense, and + is not implemented. """ raise ValueError('Raising a value to the power of an array does not make sense.') def __neg__(self) -> DescriptorArray: - """ - Negate all values in the DescriptorArray. - """ + """Negate all values in the DescriptorArray.""" new_value = -self.full_value descriptor_array = DescriptorArray.from_scipp(name=self.name, full_value=new_value) descriptor_array.name = descriptor_array.unique_name return descriptor_array def __abs__(self) -> DescriptorArray: - """ - Replace all elements in the DescriptorArray with their - absolute values. Note that this is different from the - norm of the DescriptorArray. + """Replace all elements in the DescriptorArray with their + absolute values. + + Note that this is different from the norm of the + DescriptorArray. """ new_value = abs(self.full_value) descriptor_array = DescriptorArray.from_scipp(name=self.name, full_value=new_value) @@ -668,25 +725,27 @@ def __abs__(self) -> DescriptorArray: return descriptor_array def __getitem__(self, a) -> DescriptorArray: - """ - Slice using scipp syntax. + """Slice using scipp syntax. + Defer slicing to scipp. """ - descriptor = DescriptorArray.from_scipp(name=self.name, full_value=self.full_value.__getitem__(a)) + descriptor = DescriptorArray.from_scipp( + name=self.name, full_value=self.full_value.__getitem__(a) + ) descriptor.name = descriptor.unique_name return descriptor def __delitem__(self, a): - """ - Defer slicing to scipp. + """Defer slicing to scipp. + This should fail, since scipp does not support __delitem__. """ return self.full_value.__delitem__(a) def __setitem__(self, a, b: Union[numbers.Number, list, DescriptorNumber, DescriptorArray]): - """ - __setitem via slice is not allowed, since we currently do not give back a - view to the DescriptorArray upon calling __getitem__. + """__setitem via slice is not allowed, since we currently do not + give back a view to the DescriptorArray upon calling + __getitem__. """ raise AttributeError( f'{self.__class__.__name__} cannot be edited via slicing. Edit the underlying scipp\ @@ -697,14 +756,17 @@ def __setitem__(self, a, b: Union[numbers.Number, list, DescriptorNumber, Descri def trace( self, dimension1: Optional[str] = None, dimension2: Optional[str] = None ) -> Union[DescriptorArray, DescriptorNumber]: - """ - Computes the trace over the descriptor array. The submatrix defined `dimension1` and `dimension2` must be square. - For a rank `k` tensor, the trace will run over the firs two dimensions, resulting in a rank `k-2` tensor. + """Computes the trace over the descriptor array. The submatrix + defined `dimension1` and `dimension2` must be square. For a rank + `k` tensor, the trace will run over the firs two dimensions, + resulting in a rank `k-2` tensor. :param dimension1, dimension2: First and second dimension to perform trace over. Must be in `self.dimensions`. If not defined, the trace will be taken over the first two dimensions. """ - if (dimension1 is not None and dimension2 is None) or (dimension1 is None and dimension2 is not None): + if (dimension1 is not None and dimension2 is None) or ( + dimension1 is None and dimension2 is not None + ): raise ValueError('Either both or none of `dimension1` and `dimension2` must be set.') if dimension1 is not None and dimension2 is not None: @@ -717,7 +779,9 @@ def trace( raise ValueError(f'Dimension {dim=} does not exist in `self.dimensions`.') index = self.dimensions.index(dim) axes.append(index) - remaining_dimensions = [dim for dim in self.dimensions if dim not in (dimension1, dimension2)] + remaining_dimensions = [ + dim for dim in self.dimensions if dim not in (dimension1, dimension2) + ] else: # Take the first two dimensions axes = (0, 1) @@ -725,7 +789,11 @@ def trace( remaining_dimensions = self.dimensions[2:] trace_value = np.trace(self.value, axis1=axes[0], axis2=axes[1]) - trace_variance = np.trace(self.variance, axis1=axes[0], axis2=axes[1]) if self.variance is not None else None + trace_variance = ( + np.trace(self.variance, axis1=axes[0], axis2=axes[1]) + if self.variance is not None + else None + ) # The trace reduces a rank k tensor to a k-2. if remaining_dimensions == []: # No remaining dimensions; the trace is a scalar @@ -733,16 +801,23 @@ def trace( constructor = DescriptorNumber.from_scipp else: # Else, the result is some array - trace = sc.array(dims=remaining_dimensions, values=trace_value, unit=self.unit, variances=trace_variance) + trace = sc.array( + dims=remaining_dimensions, + values=trace_value, + unit=self.unit, + variances=trace_variance, + ) constructor = DescriptorArray.from_scipp descriptor = constructor(name=self.name, full_value=trace) descriptor.name = descriptor.unique_name return descriptor - def sum(self, dim: Optional[Union[str, list]] = None) -> Union[DescriptorArray, DescriptorNumber]: - """ - Uses scipp to sum over the requested dims. + def sum( + self, dim: Optional[Union[str, list]] = None + ) -> Union[DescriptorArray, DescriptorNumber]: + """Uses scipp to sum over the requested dims. + :param dim: The dim(s) in the scipp array to sum over. If `None`, will sum over all dims. """ new_full_value = self.full_value.sum(dim=dim) @@ -783,8 +858,8 @@ def sum(self, dim: Optional[Union[str, list]] = None) -> Union[DescriptorArray, # new_full_value = operation(self._array, other) # Let scipp handle operation for uncertainty propagation def _base_unit(self) -> str: - """ - Returns the base unit of the current array. + """Returns the base unit of the current array. + For example, if the unit is `100m`, returns `m`. """ string = str(self._array.unit) diff --git a/src/easyscience/variable/descriptor_base.py b/src/easyscience/variable/descriptor_base.py index 4bb54e4a..07b4aaa1 100644 --- a/src/easyscience/variable/descriptor_base.py +++ b/src/easyscience/variable/descriptor_base.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from __future__ import annotations @@ -14,11 +13,12 @@ class DescriptorBase(SerializerComponent, metaclass=abc.ABCMeta): - """ - This is the base of all variable descriptions for models. It contains all information to describe a single - unique property of an object. This description includes a name and value as well as optionally a unit, description - and url (for reference material). Also implemented is a callback so that the value can be read/set from a linked - library object. + """This is the base of all variable descriptions for models. It + contains all information to describe a single unique property of an + object. This description includes a name and value as well as + optionally a unit, description and url (for reference material). + Also implemented is a callback so that the value can be read/set + from a linked library object. A `Descriptor` is typically something which describes part of a model and is non-fittable and generally changes the state of an object. @@ -37,9 +37,10 @@ def __init__( display_name: Optional[str] = None, parent: Optional[Any] = None, ): - """ - This is the base of variables for models. It contains all information to describe a single - unique property of an object. This description includes a name, description and url (for reference material). + """This is the base of variables for models. It contains all + information to describe a single unique property of an object. + This description includes a name, description and url (for + reference material). A `Descriptor` is typically something which describes part of a model and is non-fittable and generally changes the state of an object. @@ -86,8 +87,7 @@ def __init__( @property def name(self) -> str: - """ - Get the name of the object. + """Get the name of the object. :return: name of the object. """ @@ -96,8 +96,7 @@ def name(self) -> str: @name.setter @property_stack def name(self, new_name: str) -> None: - """ - Set the name. + """Set the name. :param new_name: name of the object. """ @@ -107,8 +106,7 @@ def name(self, new_name: str) -> None: @property def display_name(self) -> str: - """ - Get a pretty display name. + """Get a pretty display name. :return: The pretty display name. """ @@ -120,8 +118,7 @@ def display_name(self) -> str: @display_name.setter @property_stack def display_name(self, name: str) -> None: - """ - Set the pretty display name. + """Set the pretty display name. :param name: Pretty display name of the object. """ @@ -131,8 +128,7 @@ def display_name(self, name: str) -> None: @property def description(self) -> str: - """ - Get the description of the object. + """Get the description of the object. :return: description of the object. """ @@ -140,8 +136,7 @@ def description(self) -> str: @description.setter def description(self, description: str) -> None: - """ - Set the description of the object. + """Set the description of the object. :param description: description of the object. """ @@ -151,8 +146,7 @@ def description(self, description: str) -> None: @property def url(self) -> str: - """ - Get the url of the object. + """Get the url of the object. :return: url of the object. """ @@ -160,8 +154,7 @@ def url(self) -> str: @url.setter def url(self, url: str) -> None: - """ - Set the url of the object. + """Set the url of the object. :param url: url of the object. """ @@ -171,8 +164,7 @@ def url(self, url: str) -> None: @property def unique_name(self) -> str: - """ - Get the unique name of this object. + """Get the unique name of this object. :return: Unique name of this object """ @@ -180,9 +172,11 @@ def unique_name(self) -> str: @unique_name.setter def unique_name(self, new_unique_name: str): - """Set a new unique name for the object. The old name is still kept in the map. + """Set a new unique name for the object. The old name is still + kept in the map. - :param new_unique_name: New unique name for the object""" + :param new_unique_name: New unique name for the object + """ if not isinstance(new_unique_name, str): raise TypeError('Unique name has to be a string.') self._unique_name = new_unique_name diff --git a/src/easyscience/variable/descriptor_bool.py b/src/easyscience/variable/descriptor_bool.py index 72c41cd8..88135d61 100644 --- a/src/easyscience/variable/descriptor_bool.py +++ b/src/easyscience/variable/descriptor_bool.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations from typing import Any @@ -9,9 +12,7 @@ class DescriptorBool(DescriptorBase): - """ - A `Descriptor` for boolean values. - """ + """A `Descriptor` for boolean values.""" def __init__( self, @@ -39,8 +40,7 @@ def __init__( @property def value(self) -> bool: - """ - Get the value of self. + """Get the value of self. :return: Value of self """ @@ -49,8 +49,7 @@ def value(self) -> bool: @value.setter @property_stack def value(self, value: bool) -> None: - """ - Set the value of self. + """Set the value of self. :param value: New value of self :return: None diff --git a/src/easyscience/variable/descriptor_number.py b/src/easyscience/variable/descriptor_number.py index 38b233f1..b526afbf 100644 --- a/src/easyscience/variable/descriptor_number.py +++ b/src/easyscience/variable/descriptor_number.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations import numbers @@ -22,8 +25,7 @@ # Why is this a decorator? Because otherwise we would need a flag on the convert_unit method to avoid # infinite recursion. This is a bit cleaner as it avoids the need for a internal only flag on a user method. def notify_observers(func): - """ - Decorator to notify observers of a change in the descriptor. + """Decorator to notify observers of a change in the descriptor. :param func: Function to be decorated :return: Decorated function @@ -38,8 +40,9 @@ def wrapper(self, *args, **kwargs): class DescriptorNumber(DescriptorBase): - """ - A `Descriptor` for Number values with units. The internal representation is a scipp scalar. + """A `Descriptor` for Number values with units. + + The internal representation is a scipp scalar. """ def __init__( @@ -55,7 +58,7 @@ def __init__( parent: Optional[Any] = None, **kwargs: Any, # Additional keyword arguments (used for (de)serialization) ): - """Constructor for the DescriptorNumber class + """Constructor for the DescriptorNumber class. param name: Name of the descriptor param value: Value of the descriptor @@ -82,7 +85,9 @@ def __init__( raise ValueError(f'{variance=} must be positive') variance = float(variance) if not isinstance(unit, sc.Unit) and not isinstance(unit, str): - raise TypeError(f'{unit=} must be a scipp unit or a string representing a valid scipp unit') + raise TypeError( + f'{unit=} must be a scipp unit or a string representing a valid scipp unit' + ) try: self._scalar = sc.scalar(float(value), unit=unit, variance=variance) except Exception as message: @@ -102,8 +107,7 @@ def __init__( @classmethod def from_scipp(cls, name: str, full_value: Variable, **kwargs) -> DescriptorNumber: - """ - Create a DescriptorNumber from a scipp constant. + """Create a DescriptorNumber from a scipp constant. :param name: Name of the descriptor :param value: Value of the descriptor as a scipp scalar @@ -114,7 +118,13 @@ def from_scipp(cls, name: str, full_value: Variable, **kwargs) -> DescriptorNumb raise TypeError(f'{full_value=} must be a scipp scalar') if len(full_value.dims) != 0: raise TypeError(f'{full_value=} must be a scipp scalar') - return cls(name=name, value=full_value.value, unit=full_value.unit, variance=full_value.variance, **kwargs) + return cls( + name=name, + value=full_value.value, + unit=full_value.unit, + variance=full_value.variance, + **kwargs, + ) def _attach_observer(self, observer: DescriptorNumber) -> None: """Attach an observer to the descriptor.""" @@ -134,9 +144,11 @@ def _notify_observers(self) -> None: observer._update() def _validate_dependencies(self, origin=None) -> None: - """Ping all observers to check if any cyclic dependencies have been introduced. + """Ping all observers to check if any cyclic dependencies have + been introduced. - :param origin: Unique_name of the origin of this validation check. Used to avoid cyclic depenencies. + :param origin: Unique_name of the origin of this validation + check. Used to avoid cyclic depenencies. """ if origin == self.unique_name: raise RuntimeError( @@ -151,8 +163,8 @@ def _validate_dependencies(self, origin=None) -> None: @property def full_value(self) -> Variable: - """ - Get the value of self as a scipp scalar. This is should be usable for most cases. + """Get the value of self as a scipp scalar. This is should be + usable for most cases. :return: Value of self with unit. """ @@ -166,8 +178,8 @@ def full_value(self, full_value: Variable) -> None: @property def value(self) -> numbers.Number: - """ - Get the value. This should be usable for most cases. The full value can be obtained from `obj.full_value`. + """Get the value. This should be usable for most cases. The full + value can be obtained from `obj.full_value`. :return: Value of self with unit. """ @@ -177,8 +189,8 @@ def value(self) -> numbers.Number: @notify_observers @property_stack def value(self, value: numbers.Number) -> None: - """ - Set the value of self. This should be usable for most cases. The full value can be obtained from `obj.full_value`. + """Set the value of self. This should be usable for most cases. + The full value can be obtained from `obj.full_value`. :param value: New value of self """ @@ -188,8 +200,7 @@ def value(self, value: numbers.Number) -> None: @property def unit(self) -> str: - """ - Get the unit. + """Get the unit. :return: Unit as a string. """ @@ -206,8 +217,7 @@ def unit(self, unit_str: str) -> None: @property def variance(self) -> float: - """ - Get the variance. + """Get the variance. :return: variance. """ @@ -217,8 +227,7 @@ def variance(self) -> float: @notify_observers @property_stack def variance(self, variance_float: float) -> None: - """ - Set the variance. + """Set the variance. :param variance_float: Variance as a float """ @@ -232,8 +241,7 @@ def variance(self, variance_float: float) -> None: @property def error(self) -> float: - """ - The standard deviation for the parameter. + """The standard deviation for the parameter. :return: Error associated with parameter """ @@ -245,8 +253,7 @@ def error(self) -> float: @notify_observers @property_stack def error(self, value: float) -> None: - """ - Set the standard deviation for the parameter. + """Set the standard deviation for the parameter. :param value: New error value """ @@ -263,8 +270,7 @@ def error(self, value: float) -> None: # When we convert units internally, we dont want to notify observers as this can cause infinite recursion. # Therefore the convert_unit method is split into two methods, a private internal method and a public method. def _convert_unit(self, unit_str: str) -> None: - """ - Convert the value from one unit system to another. + """Convert the value from one unit system to another. :param unit_str: New unit in string form """ @@ -287,7 +293,9 @@ def set_scalar(obj, scalar): # Push to undo stack self._global_object.stack.push( - PropertyStack(self, set_scalar, old_scalar, new_scalar, text=f'Convert unit to {unit_str}') + PropertyStack( + self, set_scalar, old_scalar, new_scalar, text=f'Convert unit to {unit_str}' + ) ) # Update the scalar @@ -296,8 +304,7 @@ def set_scalar(obj, scalar): # When the user calls convert_unit, we want to notify observers of the change to propagate the change. @notify_observers def convert_unit(self, unit_str: str) -> None: - """ - Convert the value from one unit system to another. + """Convert the value from one unit system to another. :param unit_str: New unit in string form """ @@ -312,7 +319,9 @@ def __repr__(self) -> str: string = '<' string += self.__class__.__name__ + ' ' string += f"'{self._name}': " - if np.abs(self._scalar.value) > 1e4 or (np.abs(self._scalar.value) < 1e-4 and self._scalar.value != 0): + if np.abs(self._scalar.value) > 1e4 or ( + np.abs(self._scalar.value) < 1e-4 and self._scalar.value != 0 + ): # Use scientific notation for large or small values string += f'{self._scalar.value:.3e}' if self.variance: @@ -350,7 +359,9 @@ def __add__(self, other: Union[DescriptorNumber, numbers.Number]) -> DescriptorN try: other._convert_unit(self.unit) except UnitError: - raise UnitError(f'Values with units {self.unit} and {other.unit} cannot be added') from None + raise UnitError( + f'Values with units {self.unit} and {other.unit} cannot be added' + ) from None new_value = self.full_value + other.full_value other._convert_unit(original_unit) else: @@ -380,7 +391,9 @@ def __sub__(self, other: Union[DescriptorNumber, numbers.Number]) -> DescriptorN try: other._convert_unit(self.unit) except UnitError: - raise UnitError(f'Values with units {self.unit} and {other.unit} cannot be subtracted') from None + raise UnitError( + f'Values with units {self.unit} and {other.unit} cannot be subtracted' + ) from None new_value = self.full_value - other.full_value other._convert_unit(original_unit) else: @@ -493,8 +506,8 @@ def __abs__(self) -> DescriptorNumber: return descriptor_number def _base_unit(self) -> str: - """ - Extract the base unit from the unit string by removing numeric components and scientific notation. + """Extract the base unit from the unit string by removing + numeric components and scientific notation. """ string = str(self._scalar.unit) for i, letter in enumerate(string): diff --git a/src/easyscience/variable/descriptor_str.py b/src/easyscience/variable/descriptor_str.py index 17110166..c6e26f9c 100644 --- a/src/easyscience/variable/descriptor_str.py +++ b/src/easyscience/variable/descriptor_str.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from __future__ import annotations from typing import Any @@ -9,9 +12,7 @@ class DescriptorStr(DescriptorBase): - """ - A `Descriptor` for string values. - """ + """A `Descriptor` for string values.""" def __init__( self, @@ -37,8 +38,7 @@ def __init__( @property def value(self) -> str: - """ - Get the value of self. + """Get the value of self. :return: Value of self with unit. """ @@ -47,8 +47,7 @@ def value(self) -> str: @value.setter @property_stack def value(self, value: str) -> None: - """ - Set the value of self. + """Set the value of self. :param value: New value of self :return: None diff --git a/src/easyscience/variable/parameter.py b/src/easyscience/variable/parameter.py index 6ea8d1a6..36e2c7a3 100644 --- a/src/easyscience/variable/parameter.py +++ b/src/easyscience/variable/parameter.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from __future__ import annotations @@ -29,8 +28,9 @@ class Parameter(DescriptorNumber): - """ - A Parameter is a DescriptorNumber which can be used in fitting. It has additional fields to facilitate this. + """A Parameter is a DescriptorNumber which can be used in fitting. + + It has additional fields to facilitate this. """ # Used by serializer @@ -55,10 +55,10 @@ def __init__( parent: Optional[Any] = None, **kwargs: Any, # Additional keyword arguments (used for (de)serialization) ): - """ - This class is an extension of a `DescriptorNumber`. Where the descriptor was for static - objects, a `Parameter` is for dynamic objects. A parameter has the ability to be used in fitting and has - additional fields to facilitate this. + """This class is an extension of a `DescriptorNumber`. Where the + descriptor was for static objects, a `Parameter` is for dynamic + objects. A parameter has the ability to be used in fitting and + has additional fields to facilitate this. :param name: Name of this object :param value: Value of this object @@ -91,7 +91,9 @@ def __init__( if value > max: raise ValueError(f'{value=} can not be greater than {max=}') if np.isclose(min, max, rtol=1e-9, atol=0.0): - raise ValueError('The min and max bounds cannot be identical. Please use fixed=True instead to fix the value.') + raise ValueError( + 'The min and max bounds cannot be identical. Please use fixed=True instead to fix the value.' + ) if not isinstance(fixed, bool): raise TypeError('`fixed` must be either True or False') self._independent = True @@ -128,14 +130,20 @@ def from_dependency( desired_unit: str | sc.Unit | None = None, **kwargs, ) -> Parameter: # noqa: E501 - """ - Create a dependent Parameter directly from a dependency expression. + """Create a dependent Parameter directly from a dependency + expression. :param name: The name of the parameter - :param dependency_expression: The dependency expression to evaluate. This should be a string which can be evaluated by the ASTEval interpreter. - :param dependency_map: A dictionary of dependency expression symbol name and dependency object pairs. This is inserted into the asteval interpreter to resolve dependencies. - :param desired_unit: The desired unit of the dependent parameter. - :param kwargs: Additional keyword arguments to pass to the Parameter constructor. + :param dependency_expression: The dependency expression to + evaluate. This should be a string which can be evaluated by + the ASTEval interpreter. + :param dependency_map: A dictionary of dependency expression + symbol name and dependency object pairs. This is inserted + into the asteval interpreter to resolve dependencies. + :param desired_unit: The desired unit of the dependent + parameter. + :param kwargs: Additional keyword arguments to pass to the + Parameter constructor. :return: A new dependent Parameter object. """ # noqa: E501 # Set default values for required parameters for the constructor, they get overwritten by the dependency anyways @@ -151,8 +159,10 @@ def from_dependency( return parameter def _update(self) -> None: - """ - Update the parameter. This is called by the DescriptorNumbers/Parameters who have this Parameter as a dependency. + """Update the parameter. + + This is called by the DescriptorNumbers/Parameters who have this + Parameter as a dependency. """ if not self._independent: # Update the value of the parameter using the dependency interpreter @@ -161,10 +171,14 @@ def _update(self) -> None: self._scalar.unit = temporary_parameter.unit self._scalar.variance = temporary_parameter.variance self._min.value = ( - temporary_parameter.min if isinstance(temporary_parameter, Parameter) else temporary_parameter.value + temporary_parameter.min + if isinstance(temporary_parameter, Parameter) + else temporary_parameter.value ) # noqa: E501 self._max.value = ( - temporary_parameter.max if isinstance(temporary_parameter, Parameter) else temporary_parameter.value + temporary_parameter.max + if isinstance(temporary_parameter, Parameter) + else temporary_parameter.value ) # noqa: E501 self._min.unit = temporary_parameter.unit self._max.unit = temporary_parameter.unit @@ -182,8 +196,8 @@ def make_dependent_on( dependency_map: Optional[dict] = None, desired_unit: str | sc.Unit | None = None, ) -> None: - """ - Make this parameter dependent on another parameter. This will overwrite the current value, unit, variance, min and max. + """Make this parameter dependent on another parameter. This will + overwrite the current value, unit, variance, min and max. How to use the dependency map: If a parameter c has a dependency expression of 'a + b', where a and b are parameters belonging to the model class, @@ -204,10 +218,11 @@ def make_dependent_on( :param desired_unit: The desired unit of the dependent parameter. If None, the default unit of the dependency expression result is used. - """ # noqa: E501 if not isinstance(dependency_expression, str): - raise TypeError('`dependency_expression` must be a string representing a valid dependency expression.') + raise TypeError( + '`dependency_expression` must be a string representing a valid dependency expression.' + ) if not (isinstance(dependency_map, dict) or dependency_map is None): raise TypeError( '`dependency_map` must be a dictionary of dependencies and their' @@ -242,7 +257,9 @@ def make_dependent_on( self._independent = False self._dependency_string = dependency_expression self._dependency_map = dependency_map if dependency_map is not None else {} - if desired_unit is not None and not (isinstance(desired_unit, str) or isinstance(desired_unit, sc.Unit)): + if desired_unit is not None and not ( + isinstance(desired_unit, str) or isinstance(desired_unit, sc.Unit) + ): raise TypeError('`desired_unit` must be a string representing a valid unit.') self._desired_unit = desired_unit # List of allowed python constructs for the asteval interpreter @@ -283,7 +300,9 @@ def make_dependent_on( value._attach_observer(self) # Check the dependency expression for errors try: - dependency_result = self._dependency_interpreter.eval(self._clean_dependency_string, raise_errors=True) + dependency_result = self._dependency_interpreter.eval( + self._clean_dependency_string, raise_errors=True + ) except NameError as message: self._revert_dependency() raise NameError( @@ -329,9 +348,9 @@ def make_dependent_on( self._update() def make_independent(self) -> None: - """ - Make this parameter independent. - This will remove the dependency expression, the dependency map and the dependency interpreter. + """Make this parameter independent. This will remove the + dependency expression, the dependency map and the dependency + interpreter. :return: None """ @@ -349,8 +368,7 @@ def make_independent(self) -> None: @property def independent(self) -> bool: - """ - Is the parameter independent? + """Is the parameter independent? :return: True = independent, False = dependent """ @@ -364,8 +382,7 @@ def independent(self, value: bool) -> None: @property def dependency_expression(self) -> str: - """ - Get the dependency expression of this parameter. + """Get the dependency expression of this parameter. :return: The dependency expression of this parameter. """ @@ -382,8 +399,7 @@ def dependency_expression(self, new_expression: str) -> None: @property def dependency_map(self) -> Dict[str, DescriptorNumber]: - """ - Get the dependency map of this parameter. + """Get the dependency map of this parameter. :return: The dependency map of this parameter. """ @@ -394,12 +410,13 @@ def dependency_map(self) -> Dict[str, DescriptorNumber]: @dependency_map.setter def dependency_map(self, new_map: Dict[str, DescriptorNumber]) -> None: - raise AttributeError('Dependency map is read-only. Use `make_dependent_on` to change the dependency map.') + raise AttributeError( + 'Dependency map is read-only. Use `make_dependent_on` to change the dependency map.' + ) @property def value_no_call_back(self) -> numbers.Number: - """ - Get the currently hold value of self suppressing call back. + """Get the currently hold value of self suppressing call back. :return: Value of self without unit. """ @@ -407,9 +424,9 @@ def value_no_call_back(self) -> numbers.Number: @property def full_value(self) -> Variable: - """ - Get the value of self as a scipp scalar. This is should be usable for most cases. - If a scipp scalar is not acceptable then the raw value can be obtained through `obj.value`. + """Get the value of self as a scipp scalar. This is should be + usable for most cases. If a scipp scalar is not acceptable then + the raw value can be obtained through `obj.value`. :return: Value of self with unit and variance. """ @@ -423,8 +440,7 @@ def full_value(self, scalar: Variable) -> None: @property def value(self) -> numbers.Number: - """ - Get the value of self as a Number. + """Get the value of self as a Number. :return: Value of self without unit. """ @@ -437,8 +453,8 @@ def value(self) -> numbers.Number: @value.setter @property_stack def value(self, value: numbers.Number) -> None: - """ - Set the value of self. This only updates the value of the scipp scalar. + """Set the value of self. This only updates the value of the + scipp scalar. :param value: New value of self """ @@ -460,35 +476,39 @@ def value(self, value: numbers.Number) -> None: # Notify observers of the change self._notify_observers() else: - raise AttributeError('This is a dependent parameter, its value cannot be set directly.') + raise AttributeError( + 'This is a dependent parameter, its value cannot be set directly.' + ) @DescriptorNumber.variance.setter def variance(self, variance_float: float) -> None: - """ - Set the variance. + """Set the variance. :param variance_float: Variance as a float """ if self._independent: DescriptorNumber.variance.fset(self, variance_float) else: - raise AttributeError('This is a dependent parameter, its variance cannot be set directly.') + raise AttributeError( + 'This is a dependent parameter, its variance cannot be set directly.' + ) @DescriptorNumber.error.setter def error(self, value: float) -> None: - """ - Set the standard deviation for the parameter. + """Set the standard deviation for the parameter. :param value: New error value """ if self._independent: DescriptorNumber.error.fset(self, value) else: - raise AttributeError('This is a dependent parameter, its error cannot be set directly.') + raise AttributeError( + 'This is a dependent parameter, its error cannot be set directly.' + ) def _convert_unit(self, unit_str: str) -> None: - """ - Perform unit conversion. The value, max and min can change on unit change. + """Perform unit conversion. The value, max and min can change on + unit change. :param new_unit: new unit :return: None @@ -500,8 +520,8 @@ def _convert_unit(self, unit_str: str) -> None: @notify_observers def convert_unit(self, unit_str: str) -> None: - """ - Perform unit conversion. The value, max and min can change on unit change. + """Perform unit conversion. The value, max and min can change on + unit change. :param new_unit: new unit :return: None @@ -509,14 +529,16 @@ def convert_unit(self, unit_str: str) -> None: self._convert_unit(unit_str) def set_desired_unit(self, unit_str: str | sc.Unit | None) -> None: - """ - Set the desired unit for a dependent Parameter. This will convert the parameter to the desired unit. + """Set the desired unit for a dependent Parameter. This will + convert the parameter to the desired unit. :param unit_str: The desired unit as a string. """ if self._independent: - raise AttributeError('This is an independent parameter, desired unit can only be set for dependent parameters.') + raise AttributeError( + 'This is an independent parameter, desired unit can only be set for dependent parameters.' + ) if not (isinstance(unit_str, str) or isinstance(unit_str, sc.Unit) or unit_str is None): raise TypeError('`unit_str` must be a string representing a valid unit.') @@ -525,15 +547,16 @@ def set_desired_unit(self, unit_str: str | sc.Unit | None) -> None: old_unit_for_message = self.unit self._convert_unit(unit_str) except Exception as e: - raise UnitError(f'Failed to convert unit from {old_unit_for_message} to {unit_str}: {e}') + raise UnitError( + f'Failed to convert unit from {old_unit_for_message} to {unit_str}: {e}' + ) self._desired_unit = unit_str self._update() @property def min(self) -> numbers.Number: - """ - Get the minimum value for fitting. + """Get the minimum value for fitting. :return: minimum value """ @@ -553,19 +576,24 @@ def min(self, min_value: numbers.Number) -> None: if not isinstance(min_value, numbers.Number): raise TypeError('`min` must be a number') if np.isclose(min_value, self._max.value, rtol=1e-9, atol=0.0): - raise ValueError('The min and max bounds cannot be identical. Please use fixed=True instead to fix the value.') + raise ValueError( + 'The min and max bounds cannot be identical. Please use fixed=True instead to fix the value.' + ) if min_value <= self.value: self._min.value = min_value else: - raise ValueError(f'The current value ({self.value}) is smaller than the desired min value ({min_value}).') + raise ValueError( + f'The current value ({self.value}) is smaller than the desired min value ({min_value}).' + ) self._notify_observers() else: - raise AttributeError('This is a dependent parameter, its minimum value cannot be set directly.') + raise AttributeError( + 'This is a dependent parameter, its minimum value cannot be set directly.' + ) @property def max(self) -> numbers.Number: - """ - Get the maximum value for fitting. + """Get the maximum value for fitting. :return: maximum value """ @@ -585,19 +613,24 @@ def max(self, max_value: numbers.Number) -> None: if not isinstance(max_value, numbers.Number): raise TypeError('`max` must be a number') if np.isclose(max_value, self._min.value, rtol=1e-9, atol=0.0): - raise ValueError('The min and max bounds cannot be identical. Please use fixed=True instead to fix the value.') + raise ValueError( + 'The min and max bounds cannot be identical. Please use fixed=True instead to fix the value.' + ) if max_value >= self.value: self._max.value = max_value else: - raise ValueError(f'The current value ({self.value}) is greater than the desired max value ({max_value}).') + raise ValueError( + f'The current value ({self.value}) is greater than the desired max value ({max_value}).' + ) self._notify_observers() else: - raise AttributeError('This is a dependent parameter, its maximum value cannot be set directly.') + raise AttributeError( + 'This is a dependent parameter, its maximum value cannot be set directly.' + ) @property def fixed(self) -> bool: - """ - Can the parameter vary while fitting? + """Can the parameter vary while fitting? :return: True = fixed, False = can vary """ @@ -620,7 +653,9 @@ def fixed(self, fixed: bool) -> None: if self._global_object.stack.enabled: # Remove the recorded change from the stack global_object.stack.pop() - raise AttributeError('This is a dependent parameter, dependent parameters cannot be fixed.') + raise AttributeError( + 'This is a dependent parameter, dependent parameters cannot be fixed.' + ) # Is this alias really needed? @property @@ -632,7 +667,9 @@ def free(self, value: bool) -> None: self.fixed = not value def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: - """Overwrite the as_dict method to handle dependency information.""" + """Overwrite the as_dict method to handle dependency + information. + """ raw_dict = super().as_dict(skip=skip) # Add dependency information for dependent parameters @@ -649,13 +686,17 @@ def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: # Convert dependency_map to use serializer_ids raw_dict['_dependency_map_serializer_ids'] = {} for key, obj in self._dependency_map.items(): - raw_dict['_dependency_map_serializer_ids'][key] = obj._DescriptorNumber__serializer_id + raw_dict['_dependency_map_serializer_ids'][key] = ( + obj._DescriptorNumber__serializer_id + ) return raw_dict def _revert_dependency(self, skip_detach=False) -> None: - """ - Revert the dependency to the old dependency. This is used when an error is raised during setting the dependency. + """Revert the dependency to the old dependency. + + This is used when an error is raised during setting the + dependency. """ if self._previous_independent is True: self.make_independent() @@ -671,10 +712,11 @@ def _revert_dependency(self, skip_detach=False) -> None: del self._previous_independent def _process_dependency_unique_names(self, dependency_expression: str): - """ - Add the unique names of the parameters to the ASTEval interpreter. This is used to evaluate the dependency expression. + """Add the unique names of the parameters to the ASTEval + interpreter. This is used to evaluate the dependency expression. - :param dependency_expression: The dependency expression to be evaluated + :param dependency_expression: The dependency expression to be + evaluated """ # Get the unique_names from the expression string regardless of the quotes used inputted_unique_names = re.findall("('.+?')", dependency_expression) @@ -692,7 +734,9 @@ def _process_dependency_unique_names(self, dependency_expression: str): dependent_parameter = self._global_object.map.get_item_by_key(stripped_name) if isinstance(dependent_parameter, DescriptorNumber): self._dependency_map['__' + stripped_name + '__'] = dependent_parameter - clean_dependency_string = clean_dependency_string.replace(name, '__' + stripped_name + '__') + clean_dependency_string = clean_dependency_string.replace( + name, '__' + stripped_name + '__' + ) else: raise ValueError( f'The object with unique_name {stripped_name} is not a Parameter or DescriptorNumber. ' @@ -702,8 +746,8 @@ def _process_dependency_unique_names(self, dependency_expression: str): @classmethod def from_dict(cls, obj_dict: dict) -> 'Parameter': - """ - Custom deserialization to handle parameter dependencies. + """Custom deserialization to handle parameter dependencies. + Override the parent method to handle dependency information. """ # Extract dependency information before creating the parameter @@ -733,9 +777,7 @@ def __copy__(self) -> Parameter: return new_obj def __repr__(self) -> str: - """ - Return printable representation of a Parameter object. - """ + """Return printable representation of a Parameter object.""" super_str = super().__repr__() super_str = super_str[:-1] s = [] @@ -756,19 +798,29 @@ def __add__(self, other: Union[DescriptorNumber, Parameter, numbers.Number]) -> new_full_value = self.full_value + other min_value = self.min + other max_value = self.max + other - elif isinstance(other, DescriptorNumber): # Parameter inherits from DescriptorNumber and is also handled here + elif isinstance( + other, DescriptorNumber + ): # Parameter inherits from DescriptorNumber and is also handled here other_unit = other.unit try: other._convert_unit(self.unit) except UnitError: - raise UnitError(f'Values with units {self.unit} and {other.unit} cannot be added') from None + raise UnitError( + f'Values with units {self.unit} and {other.unit} cannot be added' + ) from None new_full_value = self.full_value + other.full_value - min_value = self.min + other.min if isinstance(other, Parameter) else self.min + other.value - max_value = self.max + other.max if isinstance(other, Parameter) else self.max + other.value + min_value = ( + self.min + other.min if isinstance(other, Parameter) else self.min + other.value + ) + max_value = ( + self.max + other.max if isinstance(other, Parameter) else self.max + other.value + ) other._convert_unit(other_unit) else: return NotImplemented - parameter = Parameter.from_scipp(name=self.name, full_value=new_full_value, min=min_value, max=max_value) + parameter = Parameter.from_scipp( + name=self.name, full_value=new_full_value, min=min_value, max=max_value + ) parameter.name = parameter.unique_name return parameter @@ -779,19 +831,25 @@ def __radd__(self, other: Union[DescriptorNumber, numbers.Number]) -> Parameter: new_full_value = self.full_value + other min_value = self.min + other max_value = self.max + other - elif isinstance(other, DescriptorNumber): # Parameter inherits from DescriptorNumber and is also handled here + elif isinstance( + other, DescriptorNumber + ): # Parameter inherits from DescriptorNumber and is also handled here original_unit = self.unit try: self._convert_unit(other.unit) except UnitError: - raise UnitError(f'Values with units {other.unit} and {self.unit} cannot be added') from None + raise UnitError( + f'Values with units {other.unit} and {self.unit} cannot be added' + ) from None new_full_value = self.full_value + other.full_value min_value = self.min + other.value max_value = self.max + other.value self._convert_unit(original_unit) else: return NotImplemented - parameter = Parameter.from_scipp(name=self.name, full_value=new_full_value, min=min_value, max=max_value) + parameter = Parameter.from_scipp( + name=self.name, full_value=new_full_value, min=min_value, max=max_value + ) parameter.name = parameter.unique_name return parameter @@ -802,12 +860,16 @@ def __sub__(self, other: Union[DescriptorNumber, Parameter, numbers.Number]) -> new_full_value = self.full_value - other min_value = self.min - other max_value = self.max - other - elif isinstance(other, DescriptorNumber): # Parameter inherits from DescriptorNumber and is also handled here + elif isinstance( + other, DescriptorNumber + ): # Parameter inherits from DescriptorNumber and is also handled here other_unit = other.unit try: other._convert_unit(self.unit) except UnitError: - raise UnitError(f'Values with units {self.unit} and {other.unit} cannot be subtracted') from None + raise UnitError( + f'Values with units {self.unit} and {other.unit} cannot be subtracted' + ) from None new_full_value = self.full_value - other.full_value if isinstance(other, Parameter): min_value = self.min - other.max if other.max != np.inf else -np.inf @@ -818,7 +880,9 @@ def __sub__(self, other: Union[DescriptorNumber, Parameter, numbers.Number]) -> other._convert_unit(other_unit) else: return NotImplemented - parameter = Parameter.from_scipp(name=self.name, full_value=new_full_value, min=min_value, max=max_value) + parameter = Parameter.from_scipp( + name=self.name, full_value=new_full_value, min=min_value, max=max_value + ) parameter.name = parameter.unique_name return parameter @@ -829,19 +893,25 @@ def __rsub__(self, other: Union[DescriptorNumber, numbers.Number]) -> Parameter: new_full_value = other - self.full_value min_value = other - self.max max_value = other - self.min - elif isinstance(other, DescriptorNumber): # Parameter inherits from DescriptorNumber and is also handled here + elif isinstance( + other, DescriptorNumber + ): # Parameter inherits from DescriptorNumber and is also handled here original_unit = self.unit try: self._convert_unit(other.unit) except UnitError: - raise UnitError(f'Values with units {other.unit} and {self.unit} cannot be subtracted') from None + raise UnitError( + f'Values with units {other.unit} and {self.unit} cannot be subtracted' + ) from None new_full_value = other.full_value - self.full_value min_value = other.value - self.max max_value = other.value - self.min self._convert_unit(original_unit) else: return NotImplemented - parameter = Parameter.from_scipp(name=self.name, full_value=new_full_value, min=min_value, max=max_value) + parameter = Parameter.from_scipp( + name=self.name, full_value=new_full_value, min=min_value, max=max_value + ) parameter.name = parameter.unique_name return parameter @@ -849,16 +919,22 @@ def __mul__(self, other: Union[DescriptorNumber, Parameter, numbers.Number]) -> if isinstance(other, numbers.Number): new_full_value = self.full_value * other if other == 0: - descriptor_number = DescriptorNumber.from_scipp(name=self.name, full_value=new_full_value) + descriptor_number = DescriptorNumber.from_scipp( + name=self.name, full_value=new_full_value + ) descriptor_number.name = descriptor_number.unique_name return descriptor_number combinations = [self.min * other, self.max * other] - elif isinstance(other, DescriptorNumber): # Parameter inherits from DescriptorNumber and is also handled here + elif isinstance( + other, DescriptorNumber + ): # Parameter inherits from DescriptorNumber and is also handled here new_full_value = self.full_value * other.full_value if ( other.value == 0 and type(other) is DescriptorNumber ): # Only return DescriptorNumber if other is strictly 0, i.e. not a parameter # noqa: E501 - descriptor_number = DescriptorNumber.from_scipp(name=self.name, full_value=new_full_value) + descriptor_number = DescriptorNumber.from_scipp( + name=self.name, full_value=new_full_value + ) descriptor_number.name = descriptor_number.unique_name return descriptor_number if isinstance(other, Parameter): @@ -881,7 +957,9 @@ def __mul__(self, other: Union[DescriptorNumber, Parameter, numbers.Number]) -> return NotImplemented min_value = min(combinations) max_value = max(combinations) - parameter = Parameter.from_scipp(name=self.name, full_value=new_full_value, min=min_value, max=max_value) + parameter = Parameter.from_scipp( + name=self.name, full_value=new_full_value, min=min_value, max=max_value + ) parameter._convert_unit(parameter._base_unit()) parameter.name = parameter.unique_name return parameter @@ -890,14 +968,20 @@ def __rmul__(self, other: Union[DescriptorNumber, numbers.Number]) -> Parameter: if isinstance(other, numbers.Number): new_full_value = other * self.full_value if other == 0: - descriptor_number = DescriptorNumber.from_scipp(name=self.name, full_value=new_full_value) + descriptor_number = DescriptorNumber.from_scipp( + name=self.name, full_value=new_full_value + ) descriptor_number.name = descriptor_number.unique_name return descriptor_number combinations = [other * self.min, other * self.max] - elif isinstance(other, DescriptorNumber): # Parameter inherits from DescriptorNumber and is also handled here + elif isinstance( + other, DescriptorNumber + ): # Parameter inherits from DescriptorNumber and is also handled here new_full_value = other.full_value * self.full_value if other.value == 0: - descriptor_number = DescriptorNumber.from_scipp(name=self.name, full_value=new_full_value) + descriptor_number = DescriptorNumber.from_scipp( + name=self.name, full_value=new_full_value + ) descriptor_number.name = descriptor_number.unique_name return descriptor_number combinations = [self.min * other.value, self.max * other.value] @@ -905,7 +989,9 @@ def __rmul__(self, other: Union[DescriptorNumber, numbers.Number]) -> Parameter: return NotImplemented min_value = min(combinations) max_value = max(combinations) - parameter = Parameter.from_scipp(name=self.name, full_value=new_full_value, min=min_value, max=max_value) + parameter = Parameter.from_scipp( + name=self.name, full_value=new_full_value, min=min_value, max=max_value + ) parameter._convert_unit(parameter._base_unit()) parameter.name = parameter.unique_name return parameter @@ -916,7 +1002,9 @@ def __truediv__(self, other: Union[DescriptorNumber, Parameter, numbers.Number]) raise ZeroDivisionError('Cannot divide by zero') new_full_value = self.full_value / other combinations = [self.min / other, self.max / other] - elif isinstance(other, DescriptorNumber): # Parameter inherits from DescriptorNumber and is also handled here + elif isinstance( + other, DescriptorNumber + ): # Parameter inherits from DescriptorNumber and is also handled here other_value = other.value if other_value == 0: raise ZeroDivisionError('Cannot divide by zero') @@ -951,7 +1039,9 @@ def __truediv__(self, other: Union[DescriptorNumber, Parameter, numbers.Number]) return NotImplemented min_value = min(combinations) max_value = max(combinations) - parameter = Parameter.from_scipp(name=self.name, full_value=new_full_value, min=min_value, max=max_value) + parameter = Parameter.from_scipp( + name=self.name, full_value=new_full_value, min=min_value, max=max_value + ) parameter._convert_unit(parameter._base_unit()) parameter.name = parameter.unique_name return parameter @@ -964,14 +1054,20 @@ def __rtruediv__(self, other: Union[DescriptorNumber, numbers.Number]) -> Parame new_full_value = other / self.full_value other_value = other if other_value == 0: - descriptor_number = DescriptorNumber.from_scipp(name=self.name, full_value=new_full_value) + descriptor_number = DescriptorNumber.from_scipp( + name=self.name, full_value=new_full_value + ) descriptor_number.name = descriptor_number.unique_name return descriptor_number - elif isinstance(other, DescriptorNumber): # Parameter inherits from DescriptorNumber and is also handled here + elif isinstance( + other, DescriptorNumber + ): # Parameter inherits from DescriptorNumber and is also handled here new_full_value = other.full_value / self.full_value other_value = other.value if other_value == 0: - descriptor_number = DescriptorNumber.from_scipp(name=self.name, full_value=new_full_value) + descriptor_number = DescriptorNumber.from_scipp( + name=self.name, full_value=new_full_value + ) descriptor_number.name = descriptor_number.unique_name return descriptor_number else: @@ -992,7 +1088,9 @@ def __rtruediv__(self, other: Union[DescriptorNumber, numbers.Number]) -> Parame combinations = [other_value / self.min, other_value / self.max] min_value = min(combinations) max_value = max(combinations) - parameter = Parameter.from_scipp(name=self.name, full_value=new_full_value, min=min_value, max=max_value) + parameter = Parameter.from_scipp( + name=self.name, full_value=new_full_value, min=min_value, max=max_value + ) parameter._convert_unit(parameter._base_unit()) parameter.name = parameter.unique_name return parameter @@ -1000,7 +1098,9 @@ def __rtruediv__(self, other: Union[DescriptorNumber, numbers.Number]) -> Parame def __pow__(self, other: Union[DescriptorNumber, numbers.Number]) -> Parameter: if isinstance(other, numbers.Number): exponent = other - elif type(other) is DescriptorNumber: # Strictly a DescriptorNumber, We can't raise to the power of a Parameter + elif ( + type(other) is DescriptorNumber + ): # Strictly a DescriptorNumber, We can't raise to the power of a Parameter if other.unit != 'dimensionless': raise UnitError('Exponents must be dimensionless') if other.variance is not None: @@ -1017,7 +1117,9 @@ def __pow__(self, other: Union[DescriptorNumber, numbers.Number]) -> Parameter: if np.isnan(new_full_value.value): raise ValueError('The result of the exponentiation is not a number') if exponent == 0: - descriptor_number = DescriptorNumber.from_scipp(name=self.name, full_value=new_full_value) + descriptor_number = DescriptorNumber.from_scipp( + name=self.name, full_value=new_full_value + ) descriptor_number.name = descriptor_number.unique_name return descriptor_number elif exponent < 0: @@ -1041,7 +1143,9 @@ def __pow__(self, other: Union[DescriptorNumber, numbers.Number]) -> Parameter: combinations = [combination for combination in combinations if combination >= 0] min_value = min(combinations) max_value = max(combinations) - parameter = Parameter.from_scipp(name=self.name, full_value=new_full_value, min=min_value, max=max_value) + parameter = Parameter.from_scipp( + name=self.name, full_value=new_full_value, min=min_value, max=max_value + ) parameter.name = parameter.unique_name return parameter @@ -1049,7 +1153,9 @@ def __neg__(self) -> Parameter: new_full_value = -self.full_value min_value = -self.max max_value = -self.min - parameter = Parameter.from_scipp(name=self.name, full_value=new_full_value, min=min_value, max=max_value) + parameter = Parameter.from_scipp( + name=self.name, full_value=new_full_value, min=min_value, max=max_value + ) parameter.name = parameter.unique_name return parameter @@ -1060,15 +1166,18 @@ def __abs__(self) -> Parameter: combinations.append(0.0) min_value = min(combinations) max_value = max(combinations) - parameter = Parameter.from_scipp(name=self.name, full_value=new_full_value, min=min_value, max=max_value) + parameter = Parameter.from_scipp( + name=self.name, full_value=new_full_value, min=min_value, max=max_value + ) parameter.name = parameter.unique_name return parameter def resolve_pending_dependencies(self) -> None: """Resolve pending dependencies after deserialization. - This method should be called after all parameters have been deserialized - to establish dependency relationships using serializer_ids. + This method should be called after all parameters have been + deserialized to establish dependency relationships using + serializer_ids. """ if hasattr(self, '_pending_dependency_string'): dependency_string = self._pending_dependency_string @@ -1083,7 +1192,9 @@ def resolve_pending_dependencies(self) -> None: if dep_obj is not None: dependency_map[key] = dep_obj else: - raise ValueError(f"Cannot find parameter with serializer_id '{serializer_id}'") + raise ValueError( + f"Cannot find parameter with serializer_id '{serializer_id}'" + ) # Establish the dependency relationship try: @@ -1101,9 +1212,13 @@ def resolve_pending_dependencies(self) -> None: delattr(self, '_pending_desired_unit') def _find_parameter_by_serializer_id(self, serializer_id: str) -> Optional['DescriptorNumber']: - """Find a parameter by its serializer_id from all parameters in the global map.""" + """Find a parameter by its serializer_id from all parameters in + the global map. + """ for obj in self._global_object.map._store.values(): - if isinstance(obj, DescriptorNumber) and hasattr(obj, '_DescriptorNumber__serializer_id'): + if isinstance(obj, DescriptorNumber) and hasattr( + obj, '_DescriptorNumber__serializer_id' + ): if obj._DescriptorNumber__serializer_id == serializer_id: return obj return None diff --git a/src/easyscience/variable/parameter_dependency_resolver.py b/src/easyscience/variable/parameter_dependency_resolver.py index e6b7cbd6..a4a21732 100644 --- a/src/easyscience/variable/parameter_dependency_resolver.py +++ b/src/easyscience/variable/parameter_dependency_resolver.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from __future__ import annotations @@ -12,13 +11,15 @@ def resolve_all_parameter_dependencies(obj: Any) -> None: - """ - Recursively find all Parameter objects in an object hierarchy and resolve their pending dependencies. + """Recursively find all Parameter objects in an object hierarchy and + resolve their pending dependencies. - This function should be called after deserializing a complex object that contains Parameters - with dependencies to ensure all dependency relationships are properly established. + This function should be called after deserializing a complex object + that contains Parameters with dependencies to ensure all dependency + relationships are properly established. - :param obj: The object to search for Parameters (can be a single Parameter, list, dict, or complex object) + :param obj: The object to search for Parameters (can be a single + Parameter, list, dict, or complex object) """ def _collect_parameters(item: Any, parameters: List[Parameter]) -> None: @@ -78,13 +79,15 @@ def _collect_parameters(item: Any, parameters: List[Parameter]) -> None: print(f'Successfully resolved dependencies for {resolved_count} parameter(s).') if error_count > 0: - error_message = f'Failed to resolve dependencies for {error_count} parameter(s):\n' + '\n'.join(errors) + error_message = ( + f'Failed to resolve dependencies for {error_count} parameter(s):\n' + '\n'.join(errors) + ) raise ValueError(error_message) def get_parameters_with_pending_dependencies(obj: Any) -> List[Parameter]: - """ - Find all Parameter objects in an object hierarchy that have pending dependencies. + """Find all Parameter objects in an object hierarchy that have + pending dependencies. :param obj: The object to search for Parameters :return: List of Parameters with pending dependencies @@ -92,7 +95,9 @@ def get_parameters_with_pending_dependencies(obj: Any) -> List[Parameter]: parameters_with_pending = [] def _collect_pending_parameters(item: Any) -> None: - """Recursively collect all Parameter objects with pending dependencies.""" + """Recursively collect all Parameter objects with pending + dependencies. + """ if isinstance(item, Parameter): if hasattr(item, '_pending_dependency_string'): parameters_with_pending.append(item) @@ -126,15 +131,19 @@ def _collect_pending_parameters(item: Any) -> None: return parameters_with_pending -def deserialize_and_resolve_parameters(params_data: Dict[str, Dict[str, Any]]) -> Dict[str, Parameter]: - """ - Deserialize parameters from a dictionary and resolve their dependencies. +def deserialize_and_resolve_parameters( + params_data: Dict[str, Dict[str, Any]], +) -> Dict[str, Parameter]: + """Deserialize parameters from a dictionary and resolve their + dependencies. - This is a convenience function that combines Parameter.from_dict() deserialization - with dependency resolution in a single call. + This is a convenience function that combines Parameter.from_dict() + deserialization with dependency resolution in a single call. - :param params_data: Dictionary mapping parameter names to their serialized data - :return: Dictionary mapping parameter names to deserialized Parameters with resolved dependencies + :param params_data: Dictionary mapping parameter names to their + serialized data + :return: Dictionary mapping parameter names to deserialized + Parameters with resolved dependencies """ # Deserialize all parameters first new_params = {} diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index 462d95af..00000000 --- a/tests/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project -#ifndef offsetof - #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) -#endif -#if !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif - #ifndef __fastcall - #define __fastcall - #endif -#endif -#ifndef DL_IMPORT - #define DL_IMPORT(t) t -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#define __PYX_COMMA , -#ifndef HAVE_LONG_LONG - #if PY_VERSION_HEX >= 0x02070000 - #define HAVE_LONG_LONG - #endif -#endif -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef Py_HUGE_VAL - #define Py_HUGE_VAL HUGE_VAL -#endif -#ifdef PYPY_VERSION - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#elif defined(PYSTON_VERSION) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 1 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 -#else - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 1 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) - #define CYTHON_USE_PYTYPE_LOOKUP 1 - #endif - #if PY_MAJOR_VERSION < 3 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #elif !defined(CYTHON_USE_PYLONG_INTERNALS) - #define CYTHON_USE_PYLONG_INTERNALS 1 - #endif - #ifndef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 1 - #endif - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #if PY_VERSION_HEX < 0x030300F0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #elif !defined(CYTHON_USE_UNICODE_WRITER) - #define CYTHON_USE_UNICODE_WRITER 1 - #endif - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #ifndef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 1 - #endif - #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 1 - #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) - #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) - #endif - #ifndef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) - #endif - #ifndef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) - #endif -#endif -#if !defined(CYTHON_FAST_PYCCALL) -#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) -#endif -#if CYTHON_USE_PYLONG_INTERNALS - #include "longintrepr.h" - #undef SHIFT - #undef BASE - #undef MASK - #ifdef SIZEOF_VOID_P - enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; - #endif -#endif -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 -#endif -#ifndef CYTHON_RESTRICT - #if defined(__GNUC__) - #define CYTHON_RESTRICT __restrict__ - #elif defined(_MSC_VER) && _MSC_VER >= 1400 - #define CYTHON_RESTRICT __restrict - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_RESTRICT restrict - #else - #define CYTHON_RESTRICT - #endif -#endif -#ifndef CYTHON_UNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_MAYBE_UNUSED_VAR -# if defined(__cplusplus) - template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } -# else -# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) -# endif -#endif -#ifndef CYTHON_NCP_UNUSED -# if CYTHON_COMPILING_IN_CPYTHON -# define CYTHON_NCP_UNUSED -# else -# define CYTHON_NCP_UNUSED CYTHON_UNUSED -# endif -#endif -#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) -#ifdef _MSC_VER - #ifndef _MSC_STDINT_H_ - #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned int uint32_t; - #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; - #endif - #endif -#else - #include -#endif -#ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) && __cplusplus >= 201103L - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #elif __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_attribute(fallthrough) - #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) - #else - #define CYTHON_FALLTHROUGH - #endif - #endif - #if defined(__clang__ ) && defined(__apple_build_version__) - #if __apple_build_version__ < 7000000 - #undef CYTHON_FALLTHROUGH - #define CYTHON_FALLTHROUGH - #endif - #endif -#endif - -#ifndef CYTHON_INLINE - #if defined(__clang__) - #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) - #elif defined(__GNUC__) - #define CYTHON_INLINE __inline__ - #elif defined(_MSC_VER) - #define CYTHON_INLINE __inline - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_INLINE inline - #else - #define CYTHON_INLINE - #endif -#endif - -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) - #define Py_OptimizeFlag 0 -#endif -#define __PYX_BUILD_PY_SSIZE_T "n" -#define CYTHON_FORMAT_SSIZE_T "z" -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) - #define __Pyx_DefaultClassType PyClass_Type -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" -#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#else - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#endif - #define __Pyx_DefaultClassType PyType_Type -#endif -#ifndef Py_TPFLAGS_CHECKTYPES - #define Py_TPFLAGS_CHECKTYPES 0 -#endif -#ifndef Py_TPFLAGS_HAVE_INDEX - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#ifndef Py_TPFLAGS_HAVE_NEWBUFFER - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#ifndef Py_TPFLAGS_HAVE_FINALIZE - #define Py_TPFLAGS_HAVE_FINALIZE 0 -#endif -#ifndef METH_STACKLESS - #define METH_STACKLESS 0 -#endif -#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) - #ifndef METH_FASTCALL - #define METH_FASTCALL 0x80 - #endif - typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); - typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, - Py_ssize_t nargs, PyObject *kwnames); -#else - #define __Pyx_PyCFunctionFast _PyCFunctionFast - #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords -#endif -#if CYTHON_FAST_PYCCALL -#define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) -#else -#define __Pyx_PyFastCFunction_Check(func) 0 -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) - #define PyObject_Malloc(s) PyMem_Malloc(s) - #define PyObject_Free(p) PyMem_Free(p) - #define PyObject_Realloc(p) PyMem_Realloc(p) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 - #define PyMem_RawMalloc(n) PyMem_Malloc(n) - #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) - #define PyMem_RawFree(p) PyMem_Free(p) -#endif -#if CYTHON_COMPILING_IN_PYSTON - #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) -#else - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) -#endif -#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#elif PY_VERSION_HEX >= 0x03060000 - #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() -#elif PY_VERSION_HEX >= 0x03000000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#else - #define __Pyx_PyThreadState_Current _PyThreadState_Current -#endif -#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) -#include "pythread.h" -#define Py_tss_NEEDS_INIT 0 -typedef int Py_tss_t; -static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { - *key = PyThread_create_key(); - return 0; -} -static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { - Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); - *key = Py_tss_NEEDS_INIT; - return key; -} -static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { - PyObject_Free(key); -} -static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { - return *key != Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { - PyThread_delete_key(*key); - *key = Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { - return PyThread_set_key_value(*key, value); -} -static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { - return PyThread_get_key_value(*key); -} -#endif -#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) -#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) -#else -#define __Pyx_PyDict_NewPresized(n) PyDict_New() -#endif -#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS -#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) -#else -#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) -#endif -#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) - #define CYTHON_PEP393_ENABLED 1 - #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ - 0 : _PyUnicode_Ready((PyObject *)(op))) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) - #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) - #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) - #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) - #else - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) - #endif -#else - #define CYTHON_PEP393_ENABLED 0 - #define PyUnicode_1BYTE_KIND 1 - #define PyUnicode_2BYTE_KIND 2 - #define PyUnicode_4BYTE_KIND 4 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) - #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) - #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) -#else - #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ - PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) -#endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) -#else - #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) -#endif -#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) - #define PyObject_ASCII(o) PyObject_Repr(o) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyStringObject PyUnicodeObject - #define PyString_Type PyUnicode_Type - #define PyString_Check PyUnicode_Check - #define PyString_CheckExact PyUnicode_CheckExact -#ifndef PyObject_Unicode - #define PyObject_Unicode PyObject_Str -#endif -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) - #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) -#else - #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) - #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) -#endif -#ifndef PySet_CheckExact - #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) -#endif -#if PY_VERSION_HEX >= 0x030900A4 - #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) -#else - #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) -#endif -#if CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) -#else - #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define PyNumber_Int PyNumber_Long -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBoolObject PyLongObject -#endif -#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY - #ifndef PyUnicode_InternFromString - #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) - #endif -#endif -#if PY_VERSION_HEX < 0x030200A4 - typedef long Py_hash_t; - #define __Pyx_PyInt_FromHash_t PyInt_FromLong - #define __Pyx_PyInt_AsHash_t PyInt_AsLong -#else - #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t - #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) -#else - #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) -#endif -#if CYTHON_USE_ASYNC_SLOTS - #if PY_VERSION_HEX >= 0x030500B1 - #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods - #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) - #else - #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) - #endif -#else - #define __Pyx_PyType_AsAsync(obj) NULL -#endif -#ifndef __Pyx_PyAsyncMethodsStruct - typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - } __Pyx_PyAsyncMethodsStruct; -#endif - -#if defined(WIN32) || defined(MS_WINDOWS) - #define _USE_MATH_DEFINES -#endif -#include -#ifdef NAN -#define __PYX_NAN() ((float) NAN) -#else -static CYTHON_INLINE float __PYX_NAN() { - float value; - memset(&value, 0xFF, sizeof(value)); - return value; -} -#endif -#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) -#define __Pyx_truncl trunc -#else -#define __Pyx_truncl truncl -#endif - -#define __PYX_MARK_ERR_POS(f_index, lineno) \ - { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } -#define __PYX_ERR(f_index, lineno, Ln_error) \ - { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } - -#ifndef __PYX_EXTERN_C - #ifdef __cplusplus - #define __PYX_EXTERN_C extern "C" - #else - #define __PYX_EXTERN_C extern - #endif -#endif - -#define __PYX_HAVE__easyCore__Utils__coord_cython -#define __PYX_HAVE_API__easyCore__Utils__coord_cython -/* Early includes */ -#include -#include -#include -#include -#include "numpy/arrayobject.h" -#include "numpy/ufuncobject.h" - - /* NumPy API declarations from "numpy/__init__.pxd" */ - -#include "pythread.h" -#include "pystate.h" -#ifdef _OPENMP -#include -#endif /* _OPENMP */ - -#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) -#define CYTHON_WITHOUT_ASSERTIONS -#endif - -typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; - const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; - -#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) -#define __PYX_DEFAULT_STRING_ENCODING "" -#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString -#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#define __Pyx_uchar_cast(c) ((unsigned char)c) -#define __Pyx_long_cast(x) ((long)x) -#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ - (sizeof(type) < sizeof(Py_ssize_t)) ||\ - (sizeof(type) > sizeof(Py_ssize_t) &&\ - likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX) &&\ - (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ - v == (type)PY_SSIZE_T_MIN))) ||\ - (sizeof(type) == sizeof(Py_ssize_t) &&\ - (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX))) ) -static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { - return (size_t) i < (size_t) limit; -} -#if defined (__cplusplus) && __cplusplus >= 201103L - #include - #define __Pyx_sst_abs(value) std::abs(value) -#elif SIZEOF_INT >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) abs(value) -#elif SIZEOF_LONG >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) labs(value) -#elif defined (_MSC_VER) - #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define __Pyx_sst_abs(value) llabs(value) -#elif defined (__GNUC__) - #define __Pyx_sst_abs(value) __builtin_llabs(value) -#else - #define __Pyx_sst_abs(value) ((value<0) ? -value : value) -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) -#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#else - #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize -#endif -#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) -#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) -#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) -#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) -#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { - const Py_UNICODE *u_end = u; - while (*u_end++) ; - return (size_t)(u_end - u - 1); -} -#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) -#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode -#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode -#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) -#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); -#define __Pyx_PySequence_Tuple(obj)\ - (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); -#if CYTHON_ASSUME_SAFE_MACROS -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) -#else -#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) -#endif -#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) -#else -#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) -#endif -#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - PyObject* ascii_chars_u = NULL; - PyObject* ascii_chars_b = NULL; - const char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - if (strcmp(default_encoding_c, "ascii") == 0) { - __Pyx_sys_getdefaultencoding_not_ascii = 0; - } else { - char ascii_chars[128]; - int c; - for (c = 0; c < 128; c++) { - ascii_chars[c] = c; - } - __Pyx_sys_getdefaultencoding_not_ascii = 1; - ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); - if (!ascii_chars_u) goto bad; - ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); - if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { - PyErr_Format( - PyExc_ValueError, - "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", - default_encoding_c); - goto bad; - } - Py_DECREF(ascii_chars_u); - Py_DECREF(ascii_chars_b); - } - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - Py_XDECREF(ascii_chars_u); - Py_XDECREF(ascii_chars_b); - return -1; -} -#endif -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) -#else -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -static char* __PYX_DEFAULT_STRING_ENCODING; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); - if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; - strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - return -1; -} -#endif -#endif - - -/* Test for GCC > 2.95 */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#else /* !__GNUC__ or GCC < 2.95 */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif /* __GNUC__ */ -static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } - -static PyObject *__pyx_m = NULL; -static PyObject *__pyx_d; -static PyObject *__pyx_b; -static PyObject *__pyx_cython_runtime = NULL; -static PyObject *__pyx_empty_tuple; -static PyObject *__pyx_empty_bytes; -static PyObject *__pyx_empty_unicode; -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm= __FILE__; -static const char *__pyx_filename; - -/* Header.proto */ -#if !defined(CYTHON_CCOMPLEX) - #if defined(__cplusplus) - #define CYTHON_CCOMPLEX 1 - #elif defined(_Complex_I) - #define CYTHON_CCOMPLEX 1 - #else - #define CYTHON_CCOMPLEX 0 - #endif -#endif -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - #include - #else - #include - #endif -#endif -#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) - #undef _Complex_I - #define _Complex_I 1.0fj -#endif - - -static const char *__pyx_f[] = { - "easyCore/Utils/coord_cython.pyx", - "__init__.pxd", - "stringsource", - "type.pxd", -}; -/* MemviewSliceStruct.proto */ -struct __pyx_memoryview_obj; -typedef struct { - struct __pyx_memoryview_obj *memview; - char *data; - Py_ssize_t shape[8]; - Py_ssize_t strides[8]; - Py_ssize_t suboffsets[8]; -} __Pyx_memviewslice; -#define __Pyx_MemoryView_Len(m) (m.shape[0]) - -/* Atomics.proto */ -#include -#ifndef CYTHON_ATOMICS - #define CYTHON_ATOMICS 1 -#endif -#define __pyx_atomic_int_type int -#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 ||\ - (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) &&\ - !defined(__i386__) - #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1) - #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1) - #ifdef __PYX_DEBUG_ATOMICS - #warning "Using GNU atomics" - #endif -#elif CYTHON_ATOMICS && defined(_MSC_VER) && 0 - #include - #undef __pyx_atomic_int_type - #define __pyx_atomic_int_type LONG - #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value) - #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value) - #ifdef __PYX_DEBUG_ATOMICS - #pragma message ("Using MSVC atomics") - #endif -#elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0 - #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value) - #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value) - #ifdef __PYX_DEBUG_ATOMICS - #warning "Using Intel atomics" - #endif -#else - #undef CYTHON_ATOMICS - #define CYTHON_ATOMICS 0 - #ifdef __PYX_DEBUG_ATOMICS - #warning "Not using atomics" - #endif -#endif -typedef volatile __pyx_atomic_int_type __pyx_atomic_int; -#if CYTHON_ATOMICS - #define __pyx_add_acquisition_count(memview)\ - __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock) - #define __pyx_sub_acquisition_count(memview)\ - __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock) -#else - #define __pyx_add_acquisition_count(memview)\ - __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock) - #define __pyx_sub_acquisition_count(memview)\ - __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock) -#endif - -/* ForceInitThreads.proto */ -#ifndef __PYX_FORCE_INIT_THREADS - #define __PYX_FORCE_INIT_THREADS 0 -#endif - -/* NoFastGil.proto */ -#define __Pyx_PyGILState_Ensure PyGILState_Ensure -#define __Pyx_PyGILState_Release PyGILState_Release -#define __Pyx_FastGIL_Remember() -#define __Pyx_FastGIL_Forget() -#define __Pyx_FastGilFuncInit() - -/* BufferFormatStructs.proto */ -#define IS_UNSIGNED(type) (((type) -1) > 0) -struct __Pyx_StructField_; -#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) -typedef struct { - const char* name; - struct __Pyx_StructField_* fields; - size_t size; - size_t arraysize[8]; - int ndim; - char typegroup; - char is_unsigned; - int flags; -} __Pyx_TypeInfo; -typedef struct __Pyx_StructField_ { - __Pyx_TypeInfo* type; - const char* name; - size_t offset; -} __Pyx_StructField; -typedef struct { - __Pyx_StructField* field; - size_t parent_offset; -} __Pyx_BufFmt_StackElem; -typedef struct { - __Pyx_StructField root; - __Pyx_BufFmt_StackElem* head; - size_t fmt_offset; - size_t new_count, enc_count; - size_t struct_alignment; - int is_complex; - char enc_type; - char new_packmode; - char enc_packmode; - char is_valid_array; -} __Pyx_BufFmt_Context; - - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":697 - * # in Cython to enable them only on the right systems. - * - * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< - * ctypedef npy_int16 int16_t - * ctypedef npy_int32 int32_t - */ -typedef npy_int8 __pyx_t_5numpy_int8_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":698 - * - * ctypedef npy_int8 int8_t - * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< - * ctypedef npy_int32 int32_t - * ctypedef npy_int64 int64_t - */ -typedef npy_int16 __pyx_t_5numpy_int16_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":699 - * ctypedef npy_int8 int8_t - * ctypedef npy_int16 int16_t - * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< - * ctypedef npy_int64 int64_t - * #ctypedef npy_int96 int96_t - */ -typedef npy_int32 __pyx_t_5numpy_int32_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":700 - * ctypedef npy_int16 int16_t - * ctypedef npy_int32 int32_t - * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< - * #ctypedef npy_int96 int96_t - * #ctypedef npy_int128 int128_t - */ -typedef npy_int64 __pyx_t_5numpy_int64_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":704 - * #ctypedef npy_int128 int128_t - * - * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< - * ctypedef npy_uint16 uint16_t - * ctypedef npy_uint32 uint32_t - */ -typedef npy_uint8 __pyx_t_5numpy_uint8_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":705 - * - * ctypedef npy_uint8 uint8_t - * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< - * ctypedef npy_uint32 uint32_t - * ctypedef npy_uint64 uint64_t - */ -typedef npy_uint16 __pyx_t_5numpy_uint16_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":706 - * ctypedef npy_uint8 uint8_t - * ctypedef npy_uint16 uint16_t - * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< - * ctypedef npy_uint64 uint64_t - * #ctypedef npy_uint96 uint96_t - */ -typedef npy_uint32 __pyx_t_5numpy_uint32_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":707 - * ctypedef npy_uint16 uint16_t - * ctypedef npy_uint32 uint32_t - * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< - * #ctypedef npy_uint96 uint96_t - * #ctypedef npy_uint128 uint128_t - */ -typedef npy_uint64 __pyx_t_5numpy_uint64_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":711 - * #ctypedef npy_uint128 uint128_t - * - * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< - * ctypedef npy_float64 float64_t - * #ctypedef npy_float80 float80_t - */ -typedef npy_float32 __pyx_t_5numpy_float32_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":712 - * - * ctypedef npy_float32 float32_t - * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< - * #ctypedef npy_float80 float80_t - * #ctypedef npy_float128 float128_t - */ -typedef npy_float64 __pyx_t_5numpy_float64_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":721 - * # The int types are mapped a bit surprising -- - * # numpy.int corresponds to 'l' and numpy.long to 'q' - * ctypedef npy_long int_t # <<<<<<<<<<<<<< - * ctypedef npy_longlong long_t - * ctypedef npy_longlong longlong_t - */ -typedef npy_long __pyx_t_5numpy_int_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":722 - * # numpy.int corresponds to 'l' and numpy.long to 'q' - * ctypedef npy_long int_t - * ctypedef npy_longlong long_t # <<<<<<<<<<<<<< - * ctypedef npy_longlong longlong_t - * - */ -typedef npy_longlong __pyx_t_5numpy_long_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":723 - * ctypedef npy_long int_t - * ctypedef npy_longlong long_t - * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< - * - * ctypedef npy_ulong uint_t - */ -typedef npy_longlong __pyx_t_5numpy_longlong_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":725 - * ctypedef npy_longlong longlong_t - * - * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<< - * ctypedef npy_ulonglong ulong_t - * ctypedef npy_ulonglong ulonglong_t - */ -typedef npy_ulong __pyx_t_5numpy_uint_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":726 - * - * ctypedef npy_ulong uint_t - * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<< - * ctypedef npy_ulonglong ulonglong_t - * - */ -typedef npy_ulonglong __pyx_t_5numpy_ulong_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":727 - * ctypedef npy_ulong uint_t - * ctypedef npy_ulonglong ulong_t - * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< - * - * ctypedef npy_intp intp_t - */ -typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":729 - * ctypedef npy_ulonglong ulonglong_t - * - * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< - * ctypedef npy_uintp uintp_t - * - */ -typedef npy_intp __pyx_t_5numpy_intp_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":730 - * - * ctypedef npy_intp intp_t - * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< - * - * ctypedef npy_double float_t - */ -typedef npy_uintp __pyx_t_5numpy_uintp_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":732 - * ctypedef npy_uintp uintp_t - * - * ctypedef npy_double float_t # <<<<<<<<<<<<<< - * ctypedef npy_double double_t - * ctypedef npy_longdouble longdouble_t - */ -typedef npy_double __pyx_t_5numpy_float_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":733 - * - * ctypedef npy_double float_t - * ctypedef npy_double double_t # <<<<<<<<<<<<<< - * ctypedef npy_longdouble longdouble_t - * - */ -typedef npy_double __pyx_t_5numpy_double_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":734 - * ctypedef npy_double float_t - * ctypedef npy_double double_t - * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< - * - * ctypedef npy_cfloat cfloat_t - */ -typedef npy_longdouble __pyx_t_5numpy_longdouble_t; -/* Declarations.proto */ -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - typedef ::std::complex< float > __pyx_t_float_complex; - #else - typedef float _Complex __pyx_t_float_complex; - #endif -#else - typedef struct { float real, imag; } __pyx_t_float_complex; -#endif -static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float); - -/* Declarations.proto */ -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - typedef ::std::complex< double > __pyx_t_double_complex; - #else - typedef double _Complex __pyx_t_double_complex; - #endif -#else - typedef struct { double real, imag; } __pyx_t_double_complex; -#endif -static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); - - -/*--- Type declarations ---*/ -struct __pyx_array_obj; -struct __pyx_MemviewEnum_obj; -struct __pyx_memoryview_obj; -struct __pyx_memoryviewslice_obj; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":736 - * ctypedef npy_longdouble longdouble_t - * - * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<< - * ctypedef npy_cdouble cdouble_t - * ctypedef npy_clongdouble clongdouble_t - */ -typedef npy_cfloat __pyx_t_5numpy_cfloat_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":737 - * - * ctypedef npy_cfloat cfloat_t - * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< - * ctypedef npy_clongdouble clongdouble_t - * - */ -typedef npy_cdouble __pyx_t_5numpy_cdouble_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":738 - * ctypedef npy_cfloat cfloat_t - * ctypedef npy_cdouble cdouble_t - * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<< - * - * ctypedef npy_cdouble complex_t - */ -typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t; - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":740 - * ctypedef npy_clongdouble clongdouble_t - * - * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew1(a): - */ -typedef npy_cdouble __pyx_t_5numpy_complex_t; - -/* "View.MemoryView":105 - * - * @cname("__pyx_array") - * cdef class array: # <<<<<<<<<<<<<< - * - * cdef: - */ -struct __pyx_array_obj { - PyObject_HEAD - struct __pyx_vtabstruct_array *__pyx_vtab; - char *data; - Py_ssize_t len; - char *format; - int ndim; - Py_ssize_t *_shape; - Py_ssize_t *_strides; - Py_ssize_t itemsize; - PyObject *mode; - PyObject *_format; - void (*callback_free_data)(void *); - int free_data; - int dtype_is_object; -}; - - -/* "View.MemoryView":279 - * - * @cname('__pyx_MemviewEnum') - * cdef class Enum(object): # <<<<<<<<<<<<<< - * cdef object name - * def __init__(self, name): - */ -struct __pyx_MemviewEnum_obj { - PyObject_HEAD - PyObject *name; -}; - - -/* "View.MemoryView":330 - * - * @cname('__pyx_memoryview') - * cdef class memoryview(object): # <<<<<<<<<<<<<< - * - * cdef object obj - */ -struct __pyx_memoryview_obj { - PyObject_HEAD - struct __pyx_vtabstruct_memoryview *__pyx_vtab; - PyObject *obj; - PyObject *_size; - PyObject *_array_interface; - PyThread_type_lock lock; - __pyx_atomic_int acquisition_count[2]; - __pyx_atomic_int *acquisition_count_aligned_p; - Py_buffer view; - int flags; - int dtype_is_object; - __Pyx_TypeInfo *typeinfo; -}; - - -/* "View.MemoryView":965 - * - * @cname('__pyx_memoryviewslice') - * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<< - * "Internal class for passing memoryview slices to Python" - * - */ -struct __pyx_memoryviewslice_obj { - struct __pyx_memoryview_obj __pyx_base; - __Pyx_memviewslice from_slice; - PyObject *from_object; - PyObject *(*to_object_func)(char *); - int (*to_dtype_func)(char *, PyObject *); -}; - - - -/* "View.MemoryView":105 - * - * @cname("__pyx_array") - * cdef class array: # <<<<<<<<<<<<<< - * - * cdef: - */ - -struct __pyx_vtabstruct_array { - PyObject *(*get_memview)(struct __pyx_array_obj *); -}; -static struct __pyx_vtabstruct_array *__pyx_vtabptr_array; - - -/* "View.MemoryView":330 - * - * @cname('__pyx_memoryview') - * cdef class memoryview(object): # <<<<<<<<<<<<<< - * - * cdef object obj - */ - -struct __pyx_vtabstruct_memoryview { - char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *); - PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *); - PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *); - PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *); - PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *); - PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *); - PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *); -}; -static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview; - - -/* "View.MemoryView":965 - * - * @cname('__pyx_memoryviewslice') - * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<< - * "Internal class for passing memoryview slices to Python" - * - */ - -struct __pyx_vtabstruct__memoryviewslice { - struct __pyx_vtabstruct_memoryview __pyx_base; -}; -static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice; - -/* --- Runtime support code (head) --- */ -/* Refnanny.proto */ -#ifndef CYTHON_REFNANNY - #define CYTHON_REFNANNY 0 -#endif -#if CYTHON_REFNANNY - typedef struct { - void (*INCREF)(void*, PyObject*, int); - void (*DECREF)(void*, PyObject*, int); - void (*GOTREF)(void*, PyObject*, int); - void (*GIVEREF)(void*, PyObject*, int); - void* (*SetupContext)(const char*, int, const char*); - void (*FinishContext)(void**); - } __Pyx_RefNannyAPIStruct; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); - #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; -#ifdef WITH_THREAD - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - if (acquire_gil) {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - PyGILState_Release(__pyx_gilstate_save);\ - } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - } -#else - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) -#endif - #define __Pyx_RefNannyFinishContext()\ - __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) -#else - #define __Pyx_RefNannyDeclarations - #define __Pyx_RefNannySetupContext(name, acquire_gil) - #define __Pyx_RefNannyFinishContext() - #define __Pyx_INCREF(r) Py_INCREF(r) - #define __Pyx_DECREF(r) Py_DECREF(r) - #define __Pyx_GOTREF(r) - #define __Pyx_GIVEREF(r) - #define __Pyx_XINCREF(r) Py_XINCREF(r) - #define __Pyx_XDECREF(r) Py_XDECREF(r) - #define __Pyx_XGOTREF(r) - #define __Pyx_XGIVEREF(r) -#endif -#define __Pyx_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_XDECREF(tmp);\ - } while (0) -#define __Pyx_DECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_DECREF(tmp);\ - } while (0) -#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) -#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) - -/* PyObjectGetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) -#endif - -/* GetBuiltinName.proto */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name); - -/* None.proto */ -static CYTHON_INLINE __pyx_t_5numpy_float_t __Pyx_mod___pyx_t_5numpy_float_t(__pyx_t_5numpy_float_t, __pyx_t_5numpy_float_t); - -/* RaiseArgTupleInvalid.proto */ -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); - -/* RaiseDoubleKeywords.proto */ -static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); - -/* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ - const char* function_name); - -/* PyDictVersioning.proto */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ - (version_var) = __PYX_GET_DICT_VERSION(dict);\ - (cache_var) = (value); -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ - (VAR) = __pyx_dict_cached_value;\ - } else {\ - (VAR) = __pyx_dict_cached_value = (LOOKUP);\ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ - }\ -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif - -/* GetModuleGlobalName.proto */ -#if CYTHON_USE_DICT_VERSIONS -#define __Pyx_GetModuleGlobalName(var, name) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ - (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ - __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ - PY_UINT64_T __pyx_dict_version;\ - PyObject *__pyx_dict_cached_value;\ - (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); -#else -#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) -#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); -#endif - -/* PyFunctionFastCall.proto */ -#if CYTHON_FAST_PYCALL -#define __Pyx_PyFunction_FastCall(func, args, nargs)\ - __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); -#else -#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) -#endif -#define __Pyx_BUILD_ASSERT_EXPR(cond)\ - (sizeof(char [1 - 2*!(cond)]) - 1) -#ifndef Py_MEMBER_SIZE -#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -#endif - static size_t __pyx_pyframe_localsplus_offset = 0; - #include "frameobject.h" - #define __Pxy_PyFrame_Initialize_Offsets()\ - ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ - (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) - #define __Pyx_PyFrame_GetLocalsplus(frame)\ - (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) -#endif - -/* PyCFunctionFastCall.proto */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); -#else -#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) -#endif - -/* PyObjectCall.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); -#else -#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) -#endif - -/* RaiseTooManyValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); - -/* RaiseNeedMoreValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); - -/* IterFinish.proto */ -static CYTHON_INLINE int __Pyx_IterFinish(void); - -/* UnpackItemEndCheck.proto */ -static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); - -/* PyObjectCall2Args.proto */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); - -/* PyObjectCallMethO.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); -#endif - -/* PyObjectCallOneArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); - -/* MemviewSliceInit.proto */ -#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d -#define __Pyx_MEMVIEW_DIRECT 1 -#define __Pyx_MEMVIEW_PTR 2 -#define __Pyx_MEMVIEW_FULL 4 -#define __Pyx_MEMVIEW_CONTIG 8 -#define __Pyx_MEMVIEW_STRIDED 16 -#define __Pyx_MEMVIEW_FOLLOW 32 -#define __Pyx_IS_C_CONTIG 1 -#define __Pyx_IS_F_CONTIG 2 -static int __Pyx_init_memviewslice( - struct __pyx_memoryview_obj *memview, - int ndim, - __Pyx_memviewslice *memviewslice, - int memview_is_new_reference); -static CYTHON_INLINE int __pyx_add_acquisition_count_locked( - __pyx_atomic_int *acquisition_count, PyThread_type_lock lock); -static CYTHON_INLINE int __pyx_sub_acquisition_count_locked( - __pyx_atomic_int *acquisition_count, PyThread_type_lock lock); -#define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p) -#define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview)) -#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__) -#define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__) -static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int); -static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int); - -/* PyIntBinop.proto */ -#if !CYTHON_COMPILING_IN_PYPY -static PyObject* __Pyx_PyInt_SubtractObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); -#else -#define __Pyx_PyInt_SubtractObjC(op1, op2, intval, inplace, zerodivision_check)\ - (inplace ? PyNumber_InPlaceSubtract(op1, op2) : PyNumber_Subtract(op1, op2)) -#endif - -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() PyErr_Occurred() -#endif - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* RaiseException.proto */ -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); - -/* DictGetItem.proto */ -#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY -static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key); -#define __Pyx_PyObject_Dict_GetItem(obj, name)\ - (likely(PyDict_CheckExact(obj)) ?\ - __Pyx_PyDict_GetItem(obj, name) : PyObject_GetItem(obj, name)) -#else -#define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) -#define __Pyx_PyObject_Dict_GetItem(obj, name) PyObject_GetItem(obj, name) -#endif - -/* RaiseNoneIterError.proto */ -static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); - -/* ExtTypeTest.proto */ -static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); - -/* GetTopmostException.proto */ -#if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); -#endif - -/* SaveResetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -#else -#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) -#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) -#endif - -/* PyErrExceptionMatches.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) -static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); -#else -#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) -#endif - -/* GetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* ArgTypeTest.proto */ -#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ - ((likely((Py_TYPE(obj) == type) | (none_allowed && (obj == Py_None)))) ? 1 :\ - __Pyx__ArgTypeTest(obj, type, name, exact)) -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); - -/* IncludeStringH.proto */ -#include - -/* BytesEquals.proto */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); - -/* UnicodeEquals.proto */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); - -/* StrEquals.proto */ -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals -#else -#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals -#endif - -/* None.proto */ -static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); - -/* UnaryNegOverflows.proto */ -#define UNARY_NEG_WOULD_OVERFLOW(x)\ - (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x))) - -static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ -static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *); /*proto*/ -/* GetAttr.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); - -/* GetItemInt.proto */ -#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ - __Pyx_GetItemInt_Generic(o, to_py_func(i)))) -#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, - int is_list, int wraparound, int boundscheck); - -/* ObjectGetItem.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key); -#else -#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) -#endif - -/* decode_c_string_utf16.proto */ -static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, const char *errors) { - int byteorder = 0; - return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); -} -static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16LE(const char *s, Py_ssize_t size, const char *errors) { - int byteorder = -1; - return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); -} -static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16BE(const char *s, Py_ssize_t size, const char *errors) { - int byteorder = 1; - return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); -} - -/* decode_c_string.proto */ -static CYTHON_INLINE PyObject* __Pyx_decode_c_string( - const char* cstring, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)); - -/* GetAttr3.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); - -/* SwapException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* Import.proto */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); - -/* FastTypeChecks.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); -#else -#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) -#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) -#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) -#endif -#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) - -static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ -/* ListCompAppend.proto */ -#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS -static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { - PyListObject* L = (PyListObject*) list; - Py_ssize_t len = Py_SIZE(list); - if (likely(L->allocated > len)) { - Py_INCREF(x); - PyList_SET_ITEM(list, len, x); - __Pyx_SET_SIZE(list, len + 1); - return 0; - } - return PyList_Append(list, x); -} -#else -#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) -#endif - -/* PyIntBinop.proto */ -#if !CYTHON_COMPILING_IN_PYPY -static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); -#else -#define __Pyx_PyInt_AddObjC(op1, op2, intval, inplace, zerodivision_check)\ - (inplace ? PyNumber_InPlaceAdd(op1, op2) : PyNumber_Add(op1, op2)) -#endif - -/* ListExtend.proto */ -static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) { -#if CYTHON_COMPILING_IN_CPYTHON - PyObject* none = _PyList_Extend((PyListObject*)L, v); - if (unlikely(!none)) - return -1; - Py_DECREF(none); - return 0; -#else - return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v); -#endif -} - -/* ListAppend.proto */ -#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS -static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { - PyListObject* L = (PyListObject*) list; - Py_ssize_t len = Py_SIZE(list); - if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { - Py_INCREF(x); - PyList_SET_ITEM(list, len, x); - __Pyx_SET_SIZE(list, len + 1); - return 0; - } - return PyList_Append(list, x); -} -#else -#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) -#endif - -/* None.proto */ -static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname); - -/* None.proto */ -static CYTHON_INLINE long __Pyx_div_long(long, long); - -/* ImportFrom.proto */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); - -/* HasAttr.proto */ -static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); - -/* StringJoin.proto */ -#if PY_MAJOR_VERSION < 3 -#define __Pyx_PyString_Join __Pyx_PyBytes_Join -#define __Pyx_PyBaseString_Join(s, v) (PyUnicode_CheckExact(s) ? PyUnicode_Join(s, v) : __Pyx_PyBytes_Join(s, v)) -#else -#define __Pyx_PyString_Join PyUnicode_Join -#define __Pyx_PyBaseString_Join PyUnicode_Join -#endif -#if CYTHON_COMPILING_IN_CPYTHON - #if PY_MAJOR_VERSION < 3 - #define __Pyx_PyBytes_Join _PyString_Join - #else - #define __Pyx_PyBytes_Join _PyBytes_Join - #endif -#else -static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values); -#endif - -/* PyObject_Unicode.proto */ -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyObject_Unicode(obj)\ - (likely(PyUnicode_CheckExact(obj)) ? __Pyx_NewRef(obj) : PyObject_Str(obj)) -#else -#define __Pyx_PyObject_Unicode(obj)\ - (likely(PyUnicode_CheckExact(obj)) ? __Pyx_NewRef(obj) : PyObject_Unicode(obj)) -#endif - -/* PyObject_GenericGetAttrNoDict.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr -#endif - -/* PyObject_GenericGetAttr.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr -#endif - -/* SetVTable.proto */ -static int __Pyx_SetVtable(PyObject *dict, void *vtable); - -/* PyObjectGetAttrStrNoError.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); - -/* SetupReduce.proto */ -static int __Pyx_setup_reduce(PyObject* type_obj); - -/* TypeImport.proto */ -#ifndef __PYX_HAVE_RT_ImportType_proto -#define __PYX_HAVE_RT_ImportType_proto -enum __Pyx_ImportType_CheckSize { - __Pyx_ImportType_CheckSize_Error = 0, - __Pyx_ImportType_CheckSize_Warn = 1, - __Pyx_ImportType_CheckSize_Ignore = 2 -}; -static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); -#endif - -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) -#else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); -#endif - -/* CodeObjectCache.proto */ -typedef struct { - PyCodeObject* code_object; - int code_line; -} __Pyx_CodeObjectCacheEntry; -struct __Pyx_CodeObjectCache { - int count; - int max_count; - __Pyx_CodeObjectCacheEntry* entries; -}; -static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); -static PyCodeObject *__pyx_find_code_object(int code_line); -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); - -/* AddTraceback.proto */ -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename); - -#if PY_MAJOR_VERSION < 3 - static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); - static void __Pyx_ReleaseBuffer(Py_buffer *view); -#else - #define __Pyx_GetBuffer PyObject_GetBuffer - #define __Pyx_ReleaseBuffer PyBuffer_Release -#endif - - -/* BufferStructDeclare.proto */ -typedef struct { - Py_ssize_t shape, strides, suboffsets; -} __Pyx_Buf_DimInfo; -typedef struct { - size_t refcount; - Py_buffer pybuffer; -} __Pyx_Buffer; -typedef struct { - __Pyx_Buffer *rcbuffer; - char *data; - __Pyx_Buf_DimInfo diminfo[8]; -} __Pyx_LocalBuf_ND; - -/* MemviewSliceIsContig.proto */ -static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice mvs, char order, int ndim); - -/* OverlappingSlices.proto */ -static int __pyx_slices_overlap(__Pyx_memviewslice *slice1, - __Pyx_memviewslice *slice2, - int ndim, size_t itemsize); - -/* Capsule.proto */ -static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); - -/* RealImag.proto */ -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - #define __Pyx_CREAL(z) ((z).real()) - #define __Pyx_CIMAG(z) ((z).imag()) - #else - #define __Pyx_CREAL(z) (__real__(z)) - #define __Pyx_CIMAG(z) (__imag__(z)) - #endif -#else - #define __Pyx_CREAL(z) ((z).real) - #define __Pyx_CIMAG(z) ((z).imag) -#endif -#if defined(__cplusplus) && CYTHON_CCOMPLEX\ - && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) - #define __Pyx_SET_CREAL(z,x) ((z).real(x)) - #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) -#else - #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) - #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) -#endif - -/* Arithmetic.proto */ -#if CYTHON_CCOMPLEX - #define __Pyx_c_eq_float(a, b) ((a)==(b)) - #define __Pyx_c_sum_float(a, b) ((a)+(b)) - #define __Pyx_c_diff_float(a, b) ((a)-(b)) - #define __Pyx_c_prod_float(a, b) ((a)*(b)) - #define __Pyx_c_quot_float(a, b) ((a)/(b)) - #define __Pyx_c_neg_float(a) (-(a)) - #ifdef __cplusplus - #define __Pyx_c_is_zero_float(z) ((z)==(float)0) - #define __Pyx_c_conj_float(z) (::std::conj(z)) - #if 1 - #define __Pyx_c_abs_float(z) (::std::abs(z)) - #define __Pyx_c_pow_float(a, b) (::std::pow(a, b)) - #endif - #else - #define __Pyx_c_is_zero_float(z) ((z)==0) - #define __Pyx_c_conj_float(z) (conjf(z)) - #if 1 - #define __Pyx_c_abs_float(z) (cabsf(z)) - #define __Pyx_c_pow_float(a, b) (cpowf(a, b)) - #endif - #endif -#else - static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex); - static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex); - #if 1 - static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex, __pyx_t_float_complex); - #endif -#endif - -/* Arithmetic.proto */ -#if CYTHON_CCOMPLEX - #define __Pyx_c_eq_double(a, b) ((a)==(b)) - #define __Pyx_c_sum_double(a, b) ((a)+(b)) - #define __Pyx_c_diff_double(a, b) ((a)-(b)) - #define __Pyx_c_prod_double(a, b) ((a)*(b)) - #define __Pyx_c_quot_double(a, b) ((a)/(b)) - #define __Pyx_c_neg_double(a) (-(a)) - #ifdef __cplusplus - #define __Pyx_c_is_zero_double(z) ((z)==(double)0) - #define __Pyx_c_conj_double(z) (::std::conj(z)) - #if 1 - #define __Pyx_c_abs_double(z) (::std::abs(z)) - #define __Pyx_c_pow_double(a, b) (::std::pow(a, b)) - #endif - #else - #define __Pyx_c_is_zero_double(z) ((z)==0) - #define __Pyx_c_conj_double(z) (conj(z)) - #if 1 - #define __Pyx_c_abs_double(z) (cabs(z)) - #define __Pyx_c_pow_double(a, b) (cpow(a, b)) - #endif - #endif -#else - static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex); - static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex); - #if 1 - static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex, __pyx_t_double_complex); - #endif -#endif - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value); - -/* MemviewSliceCopyTemplate.proto */ -static __Pyx_memviewslice -__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, - const char *mode, int ndim, - size_t sizeof_dtype, int contig_flag, - int dtype_is_object); - -/* TypeInfoToFormat.proto */ -struct __pyx_typeinfo_string { - char string[3]; -}; -static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *); - -/* IsLittleEndian.proto */ -static CYTHON_INLINE int __Pyx_Is_Little_Endian(void); - -/* BufferFormatCheck.proto */ -static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); -static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, - __Pyx_BufFmt_StackElem* stack, - __Pyx_TypeInfo* type); - -/* TypeInfoCompare.proto */ -static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b); - -/* MemviewSliceValidateAndInit.proto */ -static int __Pyx_ValidateAndInit_memviewslice( - int *axes_specs, - int c_or_f_flag, - int buf_flags, - int ndim, - __Pyx_TypeInfo *dtype, - __Pyx_BufFmt_StackElem stack[], - __Pyx_memviewslice *memviewslice, - PyObject *original_obj); - -/* ObjectToMemviewSlice.proto */ -static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_float_t(PyObject *, int writable_flag); - -/* ObjectToMemviewSlice.proto */ -static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_int_t(PyObject *, int writable_flag); - -/* ObjectToMemviewSlice.proto */ -static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float_t(PyObject *, int writable_flag); - -/* ObjectToMemviewSlice.proto */ -static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_d_dc_nn___pyx_t_5numpy_float_t(PyObject *, int writable_flag); - -/* ObjectToMemviewSlice.proto */ -static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_float_t(PyObject *, int writable_flag); - -/* ObjectToMemviewSlice.proto */ -static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int_t(PyObject *, int writable_flag); - -/* CheckBinaryVersion.proto */ -static int __Pyx_check_binary_version(void); - -/* InitStrings.proto */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); - -static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *__pyx_v_self); /* proto*/ -static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/ -static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/ -static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/ -static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/ -static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/ -static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/ -static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/ -static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/ -static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/ - -/* Module declarations from 'libc.string' */ - -/* Module declarations from 'libc.stdlib' */ - -/* Module declarations from 'libc.math' */ - -/* Module declarations from 'cpython.buffer' */ - -/* Module declarations from 'libc.stdio' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.type' */ -static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; - -/* Module declarations from 'cpython' */ - -/* Module declarations from 'cpython.object' */ - -/* Module declarations from 'cpython.ref' */ - -/* Module declarations from 'cpython.mem' */ - -/* Module declarations from 'numpy' */ - -/* Module declarations from 'numpy' */ -static PyTypeObject *__pyx_ptype_5numpy_dtype = 0; -static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0; -static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0; -static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0; -static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0; -static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/ - -/* Module declarations from 'cython.view' */ -static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/ - -/* Module declarations from 'cython' */ - -/* Module declarations from 'easyCore.Utils.coord_cython' */ -static PyTypeObject *__pyx_array_type = 0; -static PyTypeObject *__pyx_MemviewEnum_type = 0; -static PyTypeObject *__pyx_memoryview_type = 0; -static PyTypeObject *__pyx_memoryviewslice_type = 0; -static __Pyx_memviewslice __pyx_v_8easyCore_5Utils_12coord_cython_images_view = { 0, 0, { 0 }, { 0 }, { 0 } }; -static PyObject *generic = 0; -static PyObject *strided = 0; -static PyObject *indirect = 0; -static PyObject *contiguous = 0; -static PyObject *indirect_contiguous = 0; -static int __pyx_memoryview_thread_locks_used; -static PyThread_type_lock __pyx_memoryview_thread_locks[8]; -static void __pyx_f_8easyCore_5Utils_12coord_cython_dot_2d(__Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice); /*proto*/ -static void __pyx_f_8easyCore_5Utils_12coord_cython_dot_2d_mod(__Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice); /*proto*/ -static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/ -static void *__pyx_align_pointer(void *, size_t); /*proto*/ -static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/ -static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/ -static PyObject *_unellipsify(PyObject *, int); /*proto*/ -static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/ -static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/ -static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/ -static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/ -static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/ -static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/ -static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/ -static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/ -static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/ -static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/ -static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/ -static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/ -static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/ -static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/ -static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/ -static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/ -static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/ -static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/ -static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/ -static int __pyx_memoryview_err(PyObject *, char *); /*proto*/ -static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/ -static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/ -static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/ -static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/ -static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/ -static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/ -static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/ -static PyObject *__pyx_unpickle_Enum__set_state(struct __pyx_MemviewEnum_obj *, PyObject *); /*proto*/ -static PyObject *__pyx_format_from_typeinfo(__Pyx_TypeInfo *); /*proto*/ -static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float_t = { "float_t", NULL, sizeof(__pyx_t_5numpy_float_t), { 0 }, 0, 'R', 0, 0 }; -static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int_t = { "int_t", NULL, sizeof(__pyx_t_5numpy_int_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int_t), 0 }; -#define __Pyx_MODULE_NAME "easyCore.Utils.coord_cython" -extern int __pyx_module_is_main_easyCore__Utils__coord_cython; -int __pyx_module_is_main_easyCore__Utils__coord_cython = 0; - -/* Implementation of 'easyCore.Utils.coord_cython' */ -static PyObject *__pyx_builtin_range; -static PyObject *__pyx_builtin_ValueError; -static PyObject *__pyx_builtin_RuntimeError; -static PyObject *__pyx_builtin_ImportError; -static PyObject *__pyx_builtin_MemoryError; -static PyObject *__pyx_builtin_enumerate; -static PyObject *__pyx_builtin_TypeError; -static PyObject *__pyx_builtin_Ellipsis; -static PyObject *__pyx_builtin_id; -static PyObject *__pyx_builtin_IndexError; -static const char __pyx_k_C[] = "C"; -static const char __pyx_k_I[] = "I"; -static const char __pyx_k_J[] = "J"; -static const char __pyx_k_O[] = "O"; -static const char __pyx_k_T[] = "T{"; - static const char __pyx_k_c[] = "c"; - static const char __pyx_k_d[] = "d"; - static const char __pyx_k_i[] = "i"; - static const char __pyx_k_j[] = "j"; - static const char __pyx_k_k[] = "k"; - static const char __pyx_k_l[] = "l"; - static const char __pyx_k_m[] = "m"; - static const char __pyx_k_r[] = "r"; - static const char __pyx_k_s[] = "(%s)"; - static const char __pyx_k_t[] = "t"; - static const char __pyx_k_d2[] = "d2"; - static const char __pyx_k_da[] = "da"; - static const char __pyx_k_db[] = "db"; - static const char __pyx_k_dc[] = "dc"; - static const char __pyx_k_ds[] = "ds"; - static const char __pyx_k_id[] = "id"; - static const char __pyx_k_np[] = "np"; - static const char __pyx_k_ok[] = "ok"; - static const char __pyx_k_vs[] = "vs"; - static const char __pyx_k_1_0[] = "1.0"; - static const char __pyx_k__26[] = "^"; - static const char __pyx_k__27[] = ""; - static const char __pyx_k__28[] = ":"; -static const char __pyx_k__29[] = "}"; -static const char __pyx_k__30[] = ","; -static const char __pyx_k_fc1[] = "fc1"; -static const char __pyx_k_fc2[] = "fc2"; -static const char __pyx_k_int[] = "int_"; -static const char __pyx_k_lat[] = "lat"; -static const char __pyx_k_new[] = "__new__"; -static const char __pyx_k_obj[] = "obj"; -static const char __pyx_k_zip[] = "zip"; -static const char __pyx_k_atol[] = "atol"; -static const char __pyx_k_base[] = "base"; -static const char __pyx_k_best[] = "best"; -static const char __pyx_k_copy[] = "copy"; -static const char __pyx_k_date[] = "__date__"; -static const char __pyx_k_dict[] = "__dict__"; -static const char __pyx_k_ftol[] = "ftol"; -static const char __pyx_k_inds[] = "inds"; -static const char __pyx_k_join[] = "join"; -static const char __pyx_k_main[] = "__main__"; -static const char __pyx_k_mask[] = "mask"; -static const char __pyx_k_mode[] = "mode"; -static const char __pyx_k_name[] = "name"; -static const char __pyx_k_ndim[] = "ndim"; -static const char __pyx_k_pack[] = "pack"; -static const char __pyx_k_size[] = "size"; -static const char __pyx_k_step[] = "step"; -static const char __pyx_k_stop[] = "stop"; -static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_ASCII[] = "ASCII"; -static const char __pyx_k_array[] = "array"; -static const char __pyx_k_bestK[] = "bestK"; -static const char __pyx_k_bestk[] = "bestk"; -static const char __pyx_k_class[] = "__class__"; -static const char __pyx_k_dtype[] = "dtype"; -static const char __pyx_k_email[] = "__email__"; -static const char __pyx_k_empty[] = "empty"; -static const char __pyx_k_error[] = "error"; -static const char __pyx_k_fdist[] = "fdist"; -static const char __pyx_k_flags[] = "flags"; -static const char __pyx_k_float[] = "float_"; -static const char __pyx_k_inc_d[] = "inc_d"; -static const char __pyx_k_int_2[] = "int"; -static const char __pyx_k_numpy[] = "numpy"; -static const char __pyx_k_order[] = "order"; -static const char __pyx_k_range[] = "range"; -static const char __pyx_k_shape[] = "shape"; -static const char __pyx_k_start[] = "start"; -static const char __pyx_k_zeros[] = "zeros"; -static const char __pyx_k_arange[] = "arange"; -static const char __pyx_k_author[] = "__author__"; -static const char __pyx_k_brange[] = "brange"; -static const char __pyx_k_c_inds[] = "c_inds"; -static const char __pyx_k_crange[] = "crange"; -static const char __pyx_k_encode[] = "encode"; -static const char __pyx_k_format[] = "format"; -static const char __pyx_k_images[] = "images"; -static const char __pyx_k_import[] = "__import__"; -static const char __pyx_k_name_2[] = "__name__"; -static const char __pyx_k_pickle[] = "pickle"; -static const char __pyx_k_pre_im[] = "pre_im"; -static const char __pyx_k_reduce[] = "__reduce__"; -static const char __pyx_k_struct[] = "struct"; -static const char __pyx_k_subset[] = "subset"; -static const char __pyx_k_unpack[] = "unpack"; -static const char __pyx_k_update[] = "update"; -static const char __pyx_k_cart_f1[] = "cart_f1"; -static const char __pyx_k_cart_f2[] = "cart_f2"; -static const char __pyx_k_cart_im[] = "cart_im"; -static const char __pyx_k_fortran[] = "fortran"; -static const char __pyx_k_lattice[] = "lattice"; -static const char __pyx_k_memview[] = "memview"; -static const char __pyx_k_reshape[] = "reshape"; -static const char __pyx_k_vectors[] = "vectors"; -static const char __pyx_k_version[] = "__version__"; -static const char __pyx_k_Ellipsis[] = "Ellipsis"; -static const char __pyx_k_fcoords1[] = "fcoords1"; -static const char __pyx_k_fcoords2[] = "fcoords2"; -static const char __pyx_k_getstate[] = "__getstate__"; -static const char __pyx_k_has_ftol[] = "has_ftol"; -static const char __pyx_k_has_mask[] = "has_mask"; -static const char __pyx_k_images_t[] = "images_t"; -static const char __pyx_k_itemsize[] = "itemsize"; -static const char __pyx_k_ok_inner[] = "ok_inner"; -static const char __pyx_k_ok_outer[] = "ok_outer"; -static const char __pyx_k_pyx_type[] = "__pyx_type"; -static const char __pyx_k_setstate[] = "__setstate__"; -static const char __pyx_k_superset[] = "superset"; -static const char __pyx_k_TypeError[] = "TypeError"; -static const char __pyx_k_copyright[] = "__copyright__"; -static const char __pyx_k_enumerate[] = "enumerate"; -static const char __pyx_k_pyx_state[] = "__pyx_state"; -static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; -static const char __pyx_k_return_d2[] = "return_d2"; -static const char __pyx_k_six_moves[] = "six.moves"; -static const char __pyx_k_IndexError[] = "IndexError"; -static const char __pyx_k_ValueError[] = "ValueError"; -static const char __pyx_k_atleast_2d[] = "atleast_2d"; -static const char __pyx_k_lll_matrix[] = "lll_matrix"; -static const char __pyx_k_maintainer[] = "__maintainer__"; -static const char __pyx_k_pyx_result[] = "__pyx_result"; -static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; -static const char __pyx_k_ImportError[] = "ImportError"; -static const char __pyx_k_MemoryError[] = "MemoryError"; -static const char __pyx_k_Nov_27_2011[] = "Nov 27, 2011"; -static const char __pyx_k_PickleError[] = "PickleError"; -static const char __pyx_k_within_frac[] = "within_frac"; -static const char __pyx_k_RuntimeError[] = "RuntimeError"; -static const char __pyx_k_lll_frac_tol[] = "lll_frac_tol"; -static const char __pyx_k_pyx_checksum[] = "__pyx_checksum"; -static const char __pyx_k_stringsource[] = "stringsource"; -static const char __pyx_k_Will_Richards[] = "Will Richards"; -static const char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer"; -static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; -static const char __pyx_k_View_MemoryView[] = "View.MemoryView"; -static const char __pyx_k_allocate_buffer[] = "allocate_buffer"; -static const char __pyx_k_dtype_is_object[] = "dtype_is_object"; -static const char __pyx_k_pyx_PickleError[] = "__pyx_PickleError"; -static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; -static const char __pyx_k_pyx_unpickle_Enum[] = "__pyx_unpickle_Enum"; -static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; -static const char __pyx_k_strided_and_direct[] = ""; -static const char __pyx_k_get_lll_frac_coords[] = "get_lll_frac_coords"; -static const char __pyx_k_is_coord_subset_pbc[] = "is_coord_subset_pbc"; -static const char __pyx_k_pbc_shortest_vectors[] = "pbc_shortest_vectors"; -static const char __pyx_k_strided_and_indirect[] = ""; -static const char __pyx_k_contiguous_and_direct[] = ""; -static const char __pyx_k_wmdrichards_gmail_com[] = "wmdrichards@gmail.com"; -static const char __pyx_k_MemoryView_of_r_object[] = ""; -static const char __pyx_k_coord_list_mapping_pbc[] = "coord_list_mapping_pbc"; -static const char __pyx_k_MemoryView_of_r_at_0x_x[] = ""; -static const char __pyx_k_contiguous_and_indirect[] = ""; -static const char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'"; -static const char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d."; -static const char __pyx_k_easyCore_Utils_coord_cython[] = "easyCore.Utils.coord_cython"; -static const char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array"; -static const char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data."; -static const char __pyx_k_strided_and_direct_or_indirect[] = ""; -static const char __pyx_k_Something_wrong_with_the_inputs[] = "Something wrong with the inputs, likely duplicates in superset"; -static const char __pyx_k_Utilities_for_manipulating_coor[] = "\nUtilities for manipulating coordinates or list of coordinates, under periodic\nboundary conditions or otherwise.\n"; -static const char __pyx_k_easyCore_Utils_coord_cython_pyx[] = "easyCore/Utils/coord_cython.pyx"; -static const char __pyx_k_numpy_core_multiarray_failed_to[] = "numpy.core.multiarray failed to import"; -static const char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)"; -static const char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides"; -static const char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory."; -static const char __pyx_k_Cannot_assign_to_read_only_memor[] = "Cannot assign to read-only memoryview"; -static const char __pyx_k_Cannot_create_writable_memory_vi[] = "Cannot create writable memory view from read-only memoryview"; -static const char __pyx_k_Copyright_2011_The_Materials_Pro[] = "Copyright 2011, The Materials Project"; -static const char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array"; -static const char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd"; -static const char __pyx_k_Incompatible_checksums_s_vs_0xb0[] = "Incompatible checksums (%s vs 0xb068931 = (name))"; -static const char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported"; -static const char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s"; -static const char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported"; -static const char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)"; -static const char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object"; -static const char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)"; -static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__"; -static const char __pyx_k_numpy_core_umath_failed_to_impor[] = "numpy.core.umath failed to import"; -static const char __pyx_k_subset_is_not_a_subset_of_supers[] = "subset is not a subset of superset"; -static const char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides."; -static const char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short."; -static PyObject *__pyx_kp_s_1_0; -static PyObject *__pyx_n_s_ASCII; -static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri; -static PyObject *__pyx_n_s_C; -static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is; -static PyObject *__pyx_kp_s_Cannot_assign_to_read_only_memor; -static PyObject *__pyx_kp_s_Cannot_create_writable_memory_vi; -static PyObject *__pyx_kp_s_Cannot_index_with_type_s; -static PyObject *__pyx_kp_s_Copyright_2011_The_Materials_Pro; -static PyObject *__pyx_n_s_Ellipsis; -static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr; -static PyObject *__pyx_kp_u_Format_string_allocated_too_shor; -static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2; -static PyObject *__pyx_n_s_I; -static PyObject *__pyx_n_s_ImportError; -static PyObject *__pyx_kp_s_Incompatible_checksums_s_vs_0xb0; -static PyObject *__pyx_n_s_IndexError; -static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte; -static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr; -static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d; -static PyObject *__pyx_n_s_J; -static PyObject *__pyx_n_s_MemoryError; -static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x; -static PyObject *__pyx_kp_s_MemoryView_of_r_object; -static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor; -static PyObject *__pyx_kp_s_Nov_27_2011; -static PyObject *__pyx_n_b_O; -static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a; -static PyObject *__pyx_n_s_PickleError; -static PyObject *__pyx_n_s_RuntimeError; -static PyObject *__pyx_kp_s_Something_wrong_with_the_inputs; -static PyObject *__pyx_kp_b_T; -static PyObject *__pyx_n_s_TypeError; -static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object; -static PyObject *__pyx_n_s_ValueError; -static PyObject *__pyx_n_s_View_MemoryView; -static PyObject *__pyx_kp_s_Will_Richards; -static PyObject *__pyx_kp_b__26; -static PyObject *__pyx_kp_b__27; -static PyObject *__pyx_kp_b__28; -static PyObject *__pyx_kp_b__29; -static PyObject *__pyx_kp_u__30; -static PyObject *__pyx_n_s_allocate_buffer; -static PyObject *__pyx_n_s_arange; -static PyObject *__pyx_n_s_array; -static PyObject *__pyx_n_s_atleast_2d; -static PyObject *__pyx_n_s_atol; -static PyObject *__pyx_n_s_author; -static PyObject *__pyx_n_s_base; -static PyObject *__pyx_n_s_best; -static PyObject *__pyx_n_s_bestK; -static PyObject *__pyx_n_s_bestk; -static PyObject *__pyx_n_s_brange; -static PyObject *__pyx_n_s_c; -static PyObject *__pyx_n_u_c; -static PyObject *__pyx_n_s_c_inds; -static PyObject *__pyx_n_s_cart_f1; -static PyObject *__pyx_n_s_cart_f2; -static PyObject *__pyx_n_s_cart_im; -static PyObject *__pyx_n_s_class; -static PyObject *__pyx_n_s_cline_in_traceback; -static PyObject *__pyx_kp_s_contiguous_and_direct; -static PyObject *__pyx_kp_s_contiguous_and_indirect; -static PyObject *__pyx_n_s_coord_list_mapping_pbc; -static PyObject *__pyx_n_s_copy; -static PyObject *__pyx_n_s_copyright; -static PyObject *__pyx_n_s_crange; -static PyObject *__pyx_n_s_d; -static PyObject *__pyx_n_s_d2; -static PyObject *__pyx_n_s_da; -static PyObject *__pyx_n_s_date; -static PyObject *__pyx_n_s_db; -static PyObject *__pyx_n_s_dc; -static PyObject *__pyx_n_s_dict; -static PyObject *__pyx_n_s_ds; -static PyObject *__pyx_n_s_dtype; -static PyObject *__pyx_n_s_dtype_is_object; -static PyObject *__pyx_n_s_easyCore_Utils_coord_cython; -static PyObject *__pyx_kp_s_easyCore_Utils_coord_cython_pyx; -static PyObject *__pyx_n_s_email; -static PyObject *__pyx_n_s_empty; -static PyObject *__pyx_n_s_encode; -static PyObject *__pyx_n_s_enumerate; -static PyObject *__pyx_n_s_error; -static PyObject *__pyx_n_s_fc1; -static PyObject *__pyx_n_s_fc2; -static PyObject *__pyx_n_s_fcoords1; -static PyObject *__pyx_n_s_fcoords2; -static PyObject *__pyx_n_s_fdist; -static PyObject *__pyx_n_s_flags; -static PyObject *__pyx_n_s_float; -static PyObject *__pyx_n_s_format; -static PyObject *__pyx_n_s_fortran; -static PyObject *__pyx_n_u_fortran; -static PyObject *__pyx_n_s_ftol; -static PyObject *__pyx_n_s_get_lll_frac_coords; -static PyObject *__pyx_n_s_getstate; -static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi; -static PyObject *__pyx_n_s_has_ftol; -static PyObject *__pyx_n_s_has_mask; -static PyObject *__pyx_n_s_i; -static PyObject *__pyx_n_s_id; -static PyObject *__pyx_n_s_images; -static PyObject *__pyx_n_s_images_t; -static PyObject *__pyx_n_s_import; -static PyObject *__pyx_n_s_inc_d; -static PyObject *__pyx_n_s_inds; -static PyObject *__pyx_n_s_int; -static PyObject *__pyx_n_s_int_2; -static PyObject *__pyx_n_s_is_coord_subset_pbc; -static PyObject *__pyx_n_s_itemsize; -static PyObject *__pyx_kp_s_itemsize_0_for_cython_array; -static PyObject *__pyx_n_s_j; -static PyObject *__pyx_n_s_join; -static PyObject *__pyx_n_s_k; -static PyObject *__pyx_n_s_l; -static PyObject *__pyx_n_s_lat; -static PyObject *__pyx_n_s_lattice; -static PyObject *__pyx_n_s_lll_frac_tol; -static PyObject *__pyx_n_s_lll_matrix; -static PyObject *__pyx_n_s_m; -static PyObject *__pyx_n_s_main; -static PyObject *__pyx_n_s_maintainer; -static PyObject *__pyx_n_s_mask; -static PyObject *__pyx_n_s_memview; -static PyObject *__pyx_n_s_mode; -static PyObject *__pyx_n_s_name; -static PyObject *__pyx_n_s_name_2; -static PyObject *__pyx_n_s_ndim; -static PyObject *__pyx_n_s_new; -static PyObject *__pyx_kp_s_no_default___reduce___due_to_non; -static PyObject *__pyx_n_s_np; -static PyObject *__pyx_n_s_numpy; -static PyObject *__pyx_kp_s_numpy_core_multiarray_failed_to; -static PyObject *__pyx_kp_s_numpy_core_umath_failed_to_impor; -static PyObject *__pyx_n_s_obj; -static PyObject *__pyx_n_s_ok; -static PyObject *__pyx_n_s_ok_inner; -static PyObject *__pyx_n_s_ok_outer; -static PyObject *__pyx_n_s_order; -static PyObject *__pyx_n_s_pack; -static PyObject *__pyx_n_s_pbc_shortest_vectors; -static PyObject *__pyx_n_s_pickle; -static PyObject *__pyx_n_s_pre_im; -static PyObject *__pyx_n_s_pyx_PickleError; -static PyObject *__pyx_n_s_pyx_checksum; -static PyObject *__pyx_n_s_pyx_getbuffer; -static PyObject *__pyx_n_s_pyx_result; -static PyObject *__pyx_n_s_pyx_state; -static PyObject *__pyx_n_s_pyx_type; -static PyObject *__pyx_n_s_pyx_unpickle_Enum; -static PyObject *__pyx_n_s_pyx_vtable; -static PyObject *__pyx_n_s_r; -static PyObject *__pyx_n_s_range; -static PyObject *__pyx_n_s_reduce; -static PyObject *__pyx_n_s_reduce_cython; -static PyObject *__pyx_n_s_reduce_ex; -static PyObject *__pyx_n_s_reshape; -static PyObject *__pyx_n_s_return_d2; -static PyObject *__pyx_kp_u_s; -static PyObject *__pyx_n_s_setstate; -static PyObject *__pyx_n_s_setstate_cython; -static PyObject *__pyx_n_s_shape; -static PyObject *__pyx_n_s_six_moves; -static PyObject *__pyx_n_s_size; -static PyObject *__pyx_n_s_start; -static PyObject *__pyx_n_s_step; -static PyObject *__pyx_n_s_stop; -static PyObject *__pyx_kp_s_strided_and_direct; -static PyObject *__pyx_kp_s_strided_and_direct_or_indirect; -static PyObject *__pyx_kp_s_strided_and_indirect; -static PyObject *__pyx_kp_s_stringsource; -static PyObject *__pyx_n_s_struct; -static PyObject *__pyx_n_s_subset; -static PyObject *__pyx_kp_s_subset_is_not_a_subset_of_supers; -static PyObject *__pyx_n_s_superset; -static PyObject *__pyx_n_s_t; -static PyObject *__pyx_n_s_test; -static PyObject *__pyx_kp_s_unable_to_allocate_array_data; -static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str; -static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd; -static PyObject *__pyx_n_s_unpack; -static PyObject *__pyx_n_s_update; -static PyObject *__pyx_n_s_vectors; -static PyObject *__pyx_n_s_version; -static PyObject *__pyx_n_s_vs; -static PyObject *__pyx_n_s_within_frac; -static PyObject *__pyx_kp_s_wmdrichards_gmail_com; -static PyObject *__pyx_n_s_zeros; -static PyObject *__pyx_n_s_zip; -static PyObject *__pyx_pf_8easyCore_5Utils_12coord_cython_pbc_shortest_vectors(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_lattice, PyObject *__pyx_v_fcoords1, PyObject *__pyx_v_fcoords2, PyObject *__pyx_v_mask, PyObject *__pyx_v_return_d2, PyObject *__pyx_v_lll_frac_tol); /* proto */ -static PyObject *__pyx_pf_8easyCore_5Utils_12coord_cython_2is_coord_subset_pbc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_subset, PyObject *__pyx_v_superset, PyObject *__pyx_v_atol, PyObject *__pyx_v_mask); /* proto */ -static PyObject *__pyx_pf_8easyCore_5Utils_12coord_cython_4coord_list_mapping_pbc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_subset, PyObject *__pyx_v_superset, PyObject *__pyx_v_atol); /* proto */ -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */ -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ -static void __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */ -static Py_ssize_t __pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__len__(struct __pyx_array_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */ -static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_12__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */ -static PyObject *__pyx_pf___pyx_array___reduce_cython__(CYTHON_UNUSED struct __pyx_array_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_array_2__setstate_cython__(CYTHON_UNUSED struct __pyx_array_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ -static int __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */ -static PyObject *__pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_MemviewEnum___reduce_cython__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_MemviewEnum_2__setstate_cython__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v___pyx_state); /* proto */ -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */ -static void __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */ -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */ -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static Py_ssize_t __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_memoryview___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_memoryview_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ -static void __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_memoryviewslice___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf___pyx_memoryviewslice_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ -static PyObject *__pyx_pf_15View_dot_MemoryView___pyx_unpickle_Enum(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state); /* proto */ -static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_float_1eneg_8; -static PyObject *__pyx_int_0; -static PyObject *__pyx_int_1; -static PyObject *__pyx_int_2; -static PyObject *__pyx_int_3; -static PyObject *__pyx_int_27; -static PyObject *__pyx_int_184977713; -static PyObject *__pyx_int_neg_1; -static PyObject *__pyx_tuple_; -static PyObject *__pyx_tuple__2; -static PyObject *__pyx_tuple__3; -static PyObject *__pyx_tuple__4; -static PyObject *__pyx_tuple__5; -static PyObject *__pyx_tuple__6; -static PyObject *__pyx_tuple__7; -static PyObject *__pyx_tuple__8; -static PyObject *__pyx_tuple__9; -static PyObject *__pyx_slice__22; -static PyObject *__pyx_tuple__10; -static PyObject *__pyx_tuple__11; -static PyObject *__pyx_tuple__12; -static PyObject *__pyx_tuple__13; -static PyObject *__pyx_tuple__14; -static PyObject *__pyx_tuple__15; -static PyObject *__pyx_tuple__16; -static PyObject *__pyx_tuple__17; -static PyObject *__pyx_tuple__18; -static PyObject *__pyx_tuple__19; -static PyObject *__pyx_tuple__20; -static PyObject *__pyx_tuple__21; -static PyObject *__pyx_tuple__23; -static PyObject *__pyx_tuple__24; -static PyObject *__pyx_tuple__25; -static PyObject *__pyx_tuple__31; -static PyObject *__pyx_tuple__32; -static PyObject *__pyx_tuple__33; -static PyObject *__pyx_tuple__34; -static PyObject *__pyx_tuple__35; -static PyObject *__pyx_tuple__36; -static PyObject *__pyx_tuple__37; -static PyObject *__pyx_tuple__38; -static PyObject *__pyx_tuple__39; -static PyObject *__pyx_tuple__41; -static PyObject *__pyx_tuple__43; -static PyObject *__pyx_tuple__45; -static PyObject *__pyx_tuple__46; -static PyObject *__pyx_tuple__47; -static PyObject *__pyx_tuple__48; -static PyObject *__pyx_tuple__49; -static PyObject *__pyx_tuple__50; -static PyObject *__pyx_codeobj__40; -static PyObject *__pyx_codeobj__42; -static PyObject *__pyx_codeobj__44; -static PyObject *__pyx_codeobj__51; -/* Late includes */ - -/* "easyCore/Utils/coord_cython.pyx":39 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * cdef void dot_2d(np.float_t[:, ::1] a, np.float_t[:, ::1] b, np.float_t[:, ::1] o) nogil: # <<<<<<<<<<<<<< - * cdef int i, j, k, I, J, K - * I = a.shape[0] - */ - -static void __pyx_f_8easyCore_5Utils_12coord_cython_dot_2d(__Pyx_memviewslice __pyx_v_a, __Pyx_memviewslice __pyx_v_b, __Pyx_memviewslice __pyx_v_o) { - int __pyx_v_i; - int __pyx_v_j; - int __pyx_v_k; - int __pyx_v_I; - int __pyx_v_J; - int __pyx_v_K; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; - Py_ssize_t __pyx_t_7; - Py_ssize_t __pyx_t_8; - int __pyx_t_9; - int __pyx_t_10; - int __pyx_t_11; - Py_ssize_t __pyx_t_12; - Py_ssize_t __pyx_t_13; - Py_ssize_t __pyx_t_14; - Py_ssize_t __pyx_t_15; - - /* "easyCore/Utils/coord_cython.pyx":41 - * cdef void dot_2d(np.float_t[:, ::1] a, np.float_t[:, ::1] b, np.float_t[:, ::1] o) nogil: - * cdef int i, j, k, I, J, K - * I = a.shape[0] # <<<<<<<<<<<<<< - * J = b.shape[1] - * K = a.shape[1] - */ - __pyx_v_I = (__pyx_v_a.shape[0]); - - /* "easyCore/Utils/coord_cython.pyx":42 - * cdef int i, j, k, I, J, K - * I = a.shape[0] - * J = b.shape[1] # <<<<<<<<<<<<<< - * K = a.shape[1] - * - */ - __pyx_v_J = (__pyx_v_b.shape[1]); - - /* "easyCore/Utils/coord_cython.pyx":43 - * I = a.shape[0] - * J = b.shape[1] - * K = a.shape[1] # <<<<<<<<<<<<<< - * - * for j in range(J): - */ - __pyx_v_K = (__pyx_v_a.shape[1]); - - /* "easyCore/Utils/coord_cython.pyx":45 - * K = a.shape[1] - * - * for j in range(J): # <<<<<<<<<<<<<< - * for i in range(I): - * o[i, j] = 0 - */ - __pyx_t_1 = __pyx_v_J; - __pyx_t_2 = __pyx_t_1; - for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { - __pyx_v_j = __pyx_t_3; - - /* "easyCore/Utils/coord_cython.pyx":46 - * - * for j in range(J): - * for i in range(I): # <<<<<<<<<<<<<< - * o[i, j] = 0 - * for k in range(K): - */ - __pyx_t_4 = __pyx_v_I; - __pyx_t_5 = __pyx_t_4; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; - - /* "easyCore/Utils/coord_cython.pyx":47 - * for j in range(J): - * for i in range(I): - * o[i, j] = 0 # <<<<<<<<<<<<<< - * for k in range(K): - * for i in range(I): - */ - __pyx_t_7 = __pyx_v_i; - __pyx_t_8 = __pyx_v_j; - *((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_o.data + __pyx_t_7 * __pyx_v_o.strides[0]) )) + __pyx_t_8)) )) = 0.0; - } - - /* "easyCore/Utils/coord_cython.pyx":48 - * for i in range(I): - * o[i, j] = 0 - * for k in range(K): # <<<<<<<<<<<<<< - * for i in range(I): - * o[i, j] += a[i, k] * b[k, j] - */ - __pyx_t_4 = __pyx_v_K; - __pyx_t_5 = __pyx_t_4; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_k = __pyx_t_6; - - /* "easyCore/Utils/coord_cython.pyx":49 - * o[i, j] = 0 - * for k in range(K): - * for i in range(I): # <<<<<<<<<<<<<< - * o[i, j] += a[i, k] * b[k, j] - * - */ - __pyx_t_9 = __pyx_v_I; - __pyx_t_10 = __pyx_t_9; - for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) { - __pyx_v_i = __pyx_t_11; - - /* "easyCore/Utils/coord_cython.pyx":50 - * for k in range(K): - * for i in range(I): - * o[i, j] += a[i, k] * b[k, j] # <<<<<<<<<<<<<< - * - * @cython.boundscheck(False) - */ - __pyx_t_8 = __pyx_v_i; - __pyx_t_7 = __pyx_v_k; - __pyx_t_12 = __pyx_v_k; - __pyx_t_13 = __pyx_v_j; - __pyx_t_14 = __pyx_v_i; - __pyx_t_15 = __pyx_v_j; - *((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_o.data + __pyx_t_14 * __pyx_v_o.strides[0]) )) + __pyx_t_15)) )) += ((*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_a.data + __pyx_t_8 * __pyx_v_a.strides[0]) )) + __pyx_t_7)) ))) * (*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_b.data + __pyx_t_12 * __pyx_v_b.strides[0]) )) + __pyx_t_13)) )))); - } - } - } - - /* "easyCore/Utils/coord_cython.pyx":39 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * cdef void dot_2d(np.float_t[:, ::1] a, np.float_t[:, ::1] b, np.float_t[:, ::1] o) nogil: # <<<<<<<<<<<<<< - * cdef int i, j, k, I, J, K - * I = a.shape[0] - */ - - /* function exit code */ -} - -/* "easyCore/Utils/coord_cython.pyx":54 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * cdef void dot_2d_mod(np.float_t[:, ::1] a, np.float_t[:, ::1] b, np.float_t[:, ::1] o) nogil: # <<<<<<<<<<<<<< - * cdef int i, j, k, I, J, K - * I = a.shape[0] - */ - -static void __pyx_f_8easyCore_5Utils_12coord_cython_dot_2d_mod(__Pyx_memviewslice __pyx_v_a, __Pyx_memviewslice __pyx_v_b, __Pyx_memviewslice __pyx_v_o) { - int __pyx_v_i; - int __pyx_v_j; - int __pyx_v_k; - int __pyx_v_I; - int __pyx_v_J; - int __pyx_v_K; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; - Py_ssize_t __pyx_t_7; - Py_ssize_t __pyx_t_8; - int __pyx_t_9; - int __pyx_t_10; - int __pyx_t_11; - Py_ssize_t __pyx_t_12; - Py_ssize_t __pyx_t_13; - Py_ssize_t __pyx_t_14; - Py_ssize_t __pyx_t_15; - - /* "easyCore/Utils/coord_cython.pyx":56 - * cdef void dot_2d_mod(np.float_t[:, ::1] a, np.float_t[:, ::1] b, np.float_t[:, ::1] o) nogil: - * cdef int i, j, k, I, J, K - * I = a.shape[0] # <<<<<<<<<<<<<< - * J = b.shape[1] - * K = a.shape[1] - */ - __pyx_v_I = (__pyx_v_a.shape[0]); - - /* "easyCore/Utils/coord_cython.pyx":57 - * cdef int i, j, k, I, J, K - * I = a.shape[0] - * J = b.shape[1] # <<<<<<<<<<<<<< - * K = a.shape[1] - * - */ - __pyx_v_J = (__pyx_v_b.shape[1]); - - /* "easyCore/Utils/coord_cython.pyx":58 - * I = a.shape[0] - * J = b.shape[1] - * K = a.shape[1] # <<<<<<<<<<<<<< - * - * for j in range(J): - */ - __pyx_v_K = (__pyx_v_a.shape[1]); - - /* "easyCore/Utils/coord_cython.pyx":60 - * K = a.shape[1] - * - * for j in range(J): # <<<<<<<<<<<<<< - * for i in range(I): - * o[i, j] = 0 - */ - __pyx_t_1 = __pyx_v_J; - __pyx_t_2 = __pyx_t_1; - for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { - __pyx_v_j = __pyx_t_3; - - /* "easyCore/Utils/coord_cython.pyx":61 - * - * for j in range(J): - * for i in range(I): # <<<<<<<<<<<<<< - * o[i, j] = 0 - * for k in range(K): - */ - __pyx_t_4 = __pyx_v_I; - __pyx_t_5 = __pyx_t_4; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; - - /* "easyCore/Utils/coord_cython.pyx":62 - * for j in range(J): - * for i in range(I): - * o[i, j] = 0 # <<<<<<<<<<<<<< - * for k in range(K): - * for i in range(I): - */ - __pyx_t_7 = __pyx_v_i; - __pyx_t_8 = __pyx_v_j; - *((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_o.data + __pyx_t_7 * __pyx_v_o.strides[0]) )) + __pyx_t_8)) )) = 0.0; - } - - /* "easyCore/Utils/coord_cython.pyx":63 - * for i in range(I): - * o[i, j] = 0 - * for k in range(K): # <<<<<<<<<<<<<< - * for i in range(I): - * o[i, j] += a[i, k] % 1 * b[k, j] - */ - __pyx_t_4 = __pyx_v_K; - __pyx_t_5 = __pyx_t_4; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_k = __pyx_t_6; - - /* "easyCore/Utils/coord_cython.pyx":64 - * o[i, j] = 0 - * for k in range(K): - * for i in range(I): # <<<<<<<<<<<<<< - * o[i, j] += a[i, k] % 1 * b[k, j] - * - */ - __pyx_t_9 = __pyx_v_I; - __pyx_t_10 = __pyx_t_9; - for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) { - __pyx_v_i = __pyx_t_11; - - /* "easyCore/Utils/coord_cython.pyx":65 - * for k in range(K): - * for i in range(I): - * o[i, j] += a[i, k] % 1 * b[k, j] # <<<<<<<<<<<<<< - * - * @cython.boundscheck(False) - */ - __pyx_t_8 = __pyx_v_i; - __pyx_t_7 = __pyx_v_k; - __pyx_t_12 = __pyx_v_k; - __pyx_t_13 = __pyx_v_j; - __pyx_t_14 = __pyx_v_i; - __pyx_t_15 = __pyx_v_j; - *((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_o.data + __pyx_t_14 * __pyx_v_o.strides[0]) )) + __pyx_t_15)) )) += (__Pyx_mod___pyx_t_5numpy_float_t((*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_a.data + __pyx_t_8 * __pyx_v_a.strides[0]) )) + __pyx_t_7)) ))), 1.0) * (*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_b.data + __pyx_t_12 * __pyx_v_b.strides[0]) )) + __pyx_t_13)) )))); - } - } - } - - /* "easyCore/Utils/coord_cython.pyx":54 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * cdef void dot_2d_mod(np.float_t[:, ::1] a, np.float_t[:, ::1] b, np.float_t[:, ::1] o) nogil: # <<<<<<<<<<<<<< - * cdef int i, j, k, I, J, K - * I = a.shape[0] - */ - - /* function exit code */ -} - -/* "easyCore/Utils/coord_cython.pyx":70 - * @cython.wraparound(False) - * @cython.initializedcheck(False) - * def pbc_shortest_vectors(lattice, fcoords1, fcoords2, mask=None, return_d2=False, lll_frac_tol=None): # <<<<<<<<<<<<<< - * """ - * Returns the shortest vectors between two lists of coordinates taking into - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_8easyCore_5Utils_12coord_cython_1pbc_shortest_vectors(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_8easyCore_5Utils_12coord_cython_pbc_shortest_vectors[] = "\n Returns the shortest vectors between two lists of coordinates taking into\n account periodic boundary conditions and the lattice.\n\n Args:\n lattice: lattice to use\n fcoords1: First set of fractional coordinates. e.g., [0.5, 0.6, 0.7]\n or [[1.1, 1.2, 4.3], [0.5, 0.6, 0.7]]. Must be np.float_\n fcoords2: Second set of fractional coordinates.\n mask (int_ array): Mask of matches that are not allowed.\n i.e. if mask[1,2] == True, then subset[1] cannot be matched\n to superset[2]\n lll_frac_tol (float_ array of length 3): Fractional tolerance (per LLL lattice vector) over which\n the calculation of minimum vectors will be skipped.\n Can speed up calculation considerably for large structures.\n\n Returns:\n array of displacement vectors from fcoords1 to fcoords2\n first index is fcoords1 index, second is fcoords2 index\n "; -static PyMethodDef __pyx_mdef_8easyCore_5Utils_12coord_cython_1pbc_shortest_vectors = {"pbc_shortest_vectors", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8easyCore_5Utils_12coord_cython_1pbc_shortest_vectors, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8easyCore_5Utils_12coord_cython_pbc_shortest_vectors}; -static PyObject *__pyx_pw_8easyCore_5Utils_12coord_cython_1pbc_shortest_vectors(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_lattice = 0; - PyObject *__pyx_v_fcoords1 = 0; - PyObject *__pyx_v_fcoords2 = 0; - PyObject *__pyx_v_mask = 0; - PyObject *__pyx_v_return_d2 = 0; - PyObject *__pyx_v_lll_frac_tol = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("pbc_shortest_vectors (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_lattice,&__pyx_n_s_fcoords1,&__pyx_n_s_fcoords2,&__pyx_n_s_mask,&__pyx_n_s_return_d2,&__pyx_n_s_lll_frac_tol,0}; - PyObject* values[6] = {0,0,0,0,0,0}; - values[3] = ((PyObject *)Py_None); - values[4] = ((PyObject *)Py_False); - values[5] = ((PyObject *)Py_None); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - CYTHON_FALLTHROUGH; - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_lattice)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_fcoords1)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("pbc_shortest_vectors", 0, 3, 6, 1); __PYX_ERR(0, 70, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_fcoords2)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("pbc_shortest_vectors", 0, 3, 6, 2); __PYX_ERR(0, 70, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask); - if (value) { values[3] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 4: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_return_d2); - if (value) { values[4] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 5: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_lll_frac_tol); - if (value) { values[5] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "pbc_shortest_vectors") < 0)) __PYX_ERR(0, 70, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - CYTHON_FALLTHROUGH; - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_lattice = values[0]; - __pyx_v_fcoords1 = values[1]; - __pyx_v_fcoords2 = values[2]; - __pyx_v_mask = values[3]; - __pyx_v_return_d2 = values[4]; - __pyx_v_lll_frac_tol = values[5]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("pbc_shortest_vectors", 0, 3, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 70, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("easyCore.Utils.coord_cython.pbc_shortest_vectors", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_8easyCore_5Utils_12coord_cython_pbc_shortest_vectors(__pyx_self, __pyx_v_lattice, __pyx_v_fcoords1, __pyx_v_fcoords2, __pyx_v_mask, __pyx_v_return_d2, __pyx_v_lll_frac_tol); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_8easyCore_5Utils_12coord_cython_pbc_shortest_vectors(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_lattice, PyObject *__pyx_v_fcoords1, PyObject *__pyx_v_fcoords2, PyObject *__pyx_v_mask, PyObject *__pyx_v_return_d2, PyObject *__pyx_v_lll_frac_tol) { - __Pyx_memviewslice __pyx_v_lat = { 0, 0, { 0 }, { 0 }, { 0 } }; - int __pyx_v_i; - int __pyx_v_j; - int __pyx_v_k; - int __pyx_v_l; - int __pyx_v_I; - int __pyx_v_J; - __Pyx_memviewslice __pyx_v_fc1 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_fc2 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_cart_f1 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_cart_f2 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_cart_im = { 0, 0, { 0 }, { 0 }, { 0 } }; - int __pyx_v_has_mask; - __Pyx_memviewslice __pyx_v_m = { 0, 0, { 0 }, { 0 }, { 0 } }; - int __pyx_v_has_ftol; - __Pyx_memviewslice __pyx_v_ftol = { 0, 0, { 0 }, { 0 }, { 0 } }; - PyObject *__pyx_v_vectors = NULL; - PyObject *__pyx_v_d2 = NULL; - __Pyx_memviewslice __pyx_v_vs = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_ds = { 0, 0, { 0 }, { 0 }, { 0 } }; - __pyx_t_5numpy_float_t __pyx_v_best; - __pyx_t_5numpy_float_t __pyx_v_d; - __pyx_t_5numpy_float_t __pyx_v_da; - __pyx_t_5numpy_float_t __pyx_v_db; - __pyx_t_5numpy_float_t __pyx_v_dc; - __pyx_t_5numpy_float_t __pyx_v_fdist; - int __pyx_v_within_frac; - __Pyx_memviewslice __pyx_v_pre_im = { 0, 0, { 0 }, { 0 }, { 0 } }; - int __pyx_v_bestk; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *(*__pyx_t_6)(PyObject *); - PyObject *__pyx_t_7 = NULL; - __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } }; - Py_ssize_t __pyx_t_9; - void *__pyx_t_10; - struct __pyx_array_obj *__pyx_t_11 = NULL; - int __pyx_t_12; - __Pyx_memviewslice __pyx_t_13 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_t_14 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_t_15 = { 0, 0, { 0 }, { 0 }, { 0 } }; - int __pyx_t_16; - int __pyx_t_17; - int __pyx_t_18; - int __pyx_t_19; - int __pyx_t_20; - int __pyx_t_21; - Py_ssize_t __pyx_t_22; - Py_ssize_t __pyx_t_23; - int __pyx_t_24; - Py_ssize_t __pyx_t_25; - Py_ssize_t __pyx_t_26; - Py_ssize_t __pyx_t_27; - Py_ssize_t __pyx_t_28; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("pbc_shortest_vectors", 0); - __Pyx_INCREF(__pyx_v_fcoords1); - __Pyx_INCREF(__pyx_v_fcoords2); - - /* "easyCore/Utils/coord_cython.pyx":93 - * - * #ensure correct shape - * fcoords1, fcoords2 = np.atleast_2d(fcoords1, fcoords2) # <<<<<<<<<<<<<< - * - * - */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 93, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_atleast_2d); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 93, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = NULL; - __pyx_t_4 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_2)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_2); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - __pyx_t_4 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[3] = {__pyx_t_2, __pyx_v_fcoords1, __pyx_v_fcoords2}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_4, 2+__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[3] = {__pyx_t_2, __pyx_v_fcoords1, __pyx_v_fcoords2}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_4, 2+__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_GOTREF(__pyx_t_1); - } else - #endif - { - __pyx_t_5 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 93, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (__pyx_t_2) { - __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __pyx_t_2 = NULL; - } - __Pyx_INCREF(__pyx_v_fcoords1); - __Pyx_GIVEREF(__pyx_v_fcoords1); - PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_4, __pyx_v_fcoords1); - __Pyx_INCREF(__pyx_v_fcoords2); - __Pyx_GIVEREF(__pyx_v_fcoords2); - PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, __pyx_v_fcoords2); - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { - PyObject* sequence = __pyx_t_1; - Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); - if (unlikely(size != 2)) { - if (size > 2) __Pyx_RaiseTooManyValuesError(2); - else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(0, 93, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - if (likely(PyTuple_CheckExact(sequence))) { - __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); - } else { - __pyx_t_3 = PyList_GET_ITEM(sequence, 0); - __pyx_t_5 = PyList_GET_ITEM(sequence, 1); - } - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(__pyx_t_5); - #else - __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 93, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 93, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - } else { - Py_ssize_t index = -1; - __pyx_t_2 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 93, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_6 = Py_TYPE(__pyx_t_2)->tp_iternext; - index = 0; __pyx_t_3 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed; - __Pyx_GOTREF(__pyx_t_3); - index = 1; __pyx_t_5 = __pyx_t_6(__pyx_t_2); if (unlikely(!__pyx_t_5)) goto __pyx_L3_unpacking_failed; - __Pyx_GOTREF(__pyx_t_5); - if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_2), 2) < 0) __PYX_ERR(0, 93, __pyx_L1_error) - __pyx_t_6 = NULL; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - goto __pyx_L4_unpacking_done; - __pyx_L3_unpacking_failed:; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_6 = NULL; - if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); - __PYX_ERR(0, 93, __pyx_L1_error) - __pyx_L4_unpacking_done:; - } - __Pyx_DECREF_SET(__pyx_v_fcoords1, __pyx_t_3); - __pyx_t_3 = 0; - __Pyx_DECREF_SET(__pyx_v_fcoords2, __pyx_t_5); - __pyx_t_5 = 0; - - /* "easyCore/Utils/coord_cython.pyx":96 - * - * - * fcoords1 = lattice.get_lll_frac_coords(fcoords1) # <<<<<<<<<<<<<< - * fcoords2 = lattice.get_lll_frac_coords(fcoords2) - * - */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_lattice, __pyx_n_s_get_lll_frac_coords); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 96, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_5, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_3, __pyx_v_fcoords1) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_fcoords1); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 96, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF_SET(__pyx_v_fcoords1, __pyx_t_1); - __pyx_t_1 = 0; - - /* "easyCore/Utils/coord_cython.pyx":97 - * - * fcoords1 = lattice.get_lll_frac_coords(fcoords1) - * fcoords2 = lattice.get_lll_frac_coords(fcoords2) # <<<<<<<<<<<<<< - * - * cdef np.float_t[:, ::1] lat = np.array(lattice.lll_matrix, dtype=np.float_, copy=False, order='C') - */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_lattice, __pyx_n_s_get_lll_frac_coords); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 97, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_5, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_3, __pyx_v_fcoords2) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_fcoords2); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 97, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF_SET(__pyx_v_fcoords2, __pyx_t_1); - __pyx_t_1 = 0; - - /* "easyCore/Utils/coord_cython.pyx":99 - * fcoords2 = lattice.get_lll_frac_coords(fcoords2) - * - * cdef np.float_t[:, ::1] lat = np.array(lattice.lll_matrix, dtype=np.float_, copy=False, order='C') # <<<<<<<<<<<<<< - * - * cdef int i, j, k, l, I, J, bestK - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 99, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 99, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_lattice, __pyx_n_s_lll_matrix); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 99, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 99, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 99, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 99, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_float); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 99, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_7) < 0) __PYX_ERR(0, 99, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 99, __pyx_L1_error) - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_order, __pyx_n_s_C) < 0) __PYX_ERR(0, 99, __pyx_L1_error) - __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 99, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_float_t(__pyx_t_7, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 99, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_v_lat = __pyx_t_8; - __pyx_t_8.memview = NULL; - __pyx_t_8.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":103 - * cdef int i, j, k, l, I, J, bestK - * - * I = len(fcoords1) # <<<<<<<<<<<<<< - * J = len(fcoords2) - * - */ - __pyx_t_9 = PyObject_Length(__pyx_v_fcoords1); if (unlikely(__pyx_t_9 == ((Py_ssize_t)-1))) __PYX_ERR(0, 103, __pyx_L1_error) - __pyx_v_I = __pyx_t_9; - - /* "easyCore/Utils/coord_cython.pyx":104 - * - * I = len(fcoords1) - * J = len(fcoords2) # <<<<<<<<<<<<<< - * - * cdef np.float_t[:, ::1] fc1 = fcoords1 - */ - __pyx_t_9 = PyObject_Length(__pyx_v_fcoords2); if (unlikely(__pyx_t_9 == ((Py_ssize_t)-1))) __PYX_ERR(0, 104, __pyx_L1_error) - __pyx_v_J = __pyx_t_9; - - /* "easyCore/Utils/coord_cython.pyx":106 - * J = len(fcoords2) - * - * cdef np.float_t[:, ::1] fc1 = fcoords1 # <<<<<<<<<<<<<< - * cdef np.float_t[:, ::1] fc2 = fcoords2 - * - */ - __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_float_t(__pyx_v_fcoords1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 106, __pyx_L1_error) - __pyx_v_fc1 = __pyx_t_8; - __pyx_t_8.memview = NULL; - __pyx_t_8.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":107 - * - * cdef np.float_t[:, ::1] fc1 = fcoords1 - * cdef np.float_t[:, ::1] fc2 = fcoords2 # <<<<<<<<<<<<<< - * - * cdef np.float_t[:, ::1] cart_f1 = malloc(3 * I * sizeof(np.float_t)) - */ - __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_float_t(__pyx_v_fcoords2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 107, __pyx_L1_error) - __pyx_v_fc2 = __pyx_t_8; - __pyx_t_8.memview = NULL; - __pyx_t_8.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":109 - * cdef np.float_t[:, ::1] fc2 = fcoords2 - * - * cdef np.float_t[:, ::1] cart_f1 = malloc(3 * I * sizeof(np.float_t)) # <<<<<<<<<<<<<< - * cdef np.float_t[:, ::1] cart_f2 = malloc(3 * J * sizeof(np.float_t)) - * cdef np.float_t[:, ::1] cart_im = malloc(81 * sizeof(np.float_t)) - */ - __pyx_t_10 = malloc(((3 * __pyx_v_I) * (sizeof(__pyx_t_5numpy_float_t)))); - if (!__pyx_t_10) { - PyErr_SetString(PyExc_ValueError,"Cannot create cython.array from NULL pointer"); - __PYX_ERR(0, 109, __pyx_L1_error) - } - __pyx_t_1 = __pyx_format_from_typeinfo(&__Pyx_TypeInfo_nn___pyx_t_5numpy_float_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 109, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_7 = Py_BuildValue((char*) "(" __PYX_BUILD_PY_SSIZE_T __PYX_BUILD_PY_SSIZE_T ")", ((Py_ssize_t)__pyx_v_I), ((Py_ssize_t)3)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 109, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_11 = __pyx_array_new(__pyx_t_7, sizeof(__pyx_t_5numpy_float_t), PyBytes_AS_STRING(__pyx_t_1), (char *) "c", (char *) __pyx_t_10); - if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 109, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_float_t(((PyObject *)__pyx_t_11), PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 109, __pyx_L1_error) - __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0; - __pyx_v_cart_f1 = __pyx_t_8; - __pyx_t_8.memview = NULL; - __pyx_t_8.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":110 - * - * cdef np.float_t[:, ::1] cart_f1 = malloc(3 * I * sizeof(np.float_t)) - * cdef np.float_t[:, ::1] cart_f2 = malloc(3 * J * sizeof(np.float_t)) # <<<<<<<<<<<<<< - * cdef np.float_t[:, ::1] cart_im = malloc(81 * sizeof(np.float_t)) - * - */ - __pyx_t_10 = malloc(((3 * __pyx_v_J) * (sizeof(__pyx_t_5numpy_float_t)))); - if (!__pyx_t_10) { - PyErr_SetString(PyExc_ValueError,"Cannot create cython.array from NULL pointer"); - __PYX_ERR(0, 110, __pyx_L1_error) - } - __pyx_t_7 = __pyx_format_from_typeinfo(&__Pyx_TypeInfo_nn___pyx_t_5numpy_float_t); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_1 = Py_BuildValue((char*) "(" __PYX_BUILD_PY_SSIZE_T __PYX_BUILD_PY_SSIZE_T ")", ((Py_ssize_t)__pyx_v_J), ((Py_ssize_t)3)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_11 = __pyx_array_new(__pyx_t_1, sizeof(__pyx_t_5numpy_float_t), PyBytes_AS_STRING(__pyx_t_7), (char *) "c", (char *) __pyx_t_10); - if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_float_t(((PyObject *)__pyx_t_11), PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 110, __pyx_L1_error) - __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0; - __pyx_v_cart_f2 = __pyx_t_8; - __pyx_t_8.memview = NULL; - __pyx_t_8.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":111 - * cdef np.float_t[:, ::1] cart_f1 = malloc(3 * I * sizeof(np.float_t)) - * cdef np.float_t[:, ::1] cart_f2 = malloc(3 * J * sizeof(np.float_t)) - * cdef np.float_t[:, ::1] cart_im = malloc(81 * sizeof(np.float_t)) # <<<<<<<<<<<<<< - * - * cdef bint has_mask = mask is not None - */ - __pyx_t_10 = malloc((81 * (sizeof(__pyx_t_5numpy_float_t)))); - if (!__pyx_t_10) { - PyErr_SetString(PyExc_ValueError,"Cannot create cython.array from NULL pointer"); - __PYX_ERR(0, 111, __pyx_L1_error) - } - __pyx_t_1 = __pyx_format_from_typeinfo(&__Pyx_TypeInfo_nn___pyx_t_5numpy_float_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_7 = Py_BuildValue((char*) "(" __PYX_BUILD_PY_SSIZE_T __PYX_BUILD_PY_SSIZE_T ")", ((Py_ssize_t)27), ((Py_ssize_t)3)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_11 = __pyx_array_new(__pyx_t_7, sizeof(__pyx_t_5numpy_float_t), PyBytes_AS_STRING(__pyx_t_1), (char *) "c", (char *) __pyx_t_10); - if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_float_t(((PyObject *)__pyx_t_11), PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 111, __pyx_L1_error) - __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0; - __pyx_v_cart_im = __pyx_t_8; - __pyx_t_8.memview = NULL; - __pyx_t_8.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":113 - * cdef np.float_t[:, ::1] cart_im = malloc(81 * sizeof(np.float_t)) - * - * cdef bint has_mask = mask is not None # <<<<<<<<<<<<<< - * cdef np.int_t[:, :] m - * if has_mask: - */ - __pyx_t_12 = (__pyx_v_mask != Py_None); - __pyx_v_has_mask = __pyx_t_12; - - /* "easyCore/Utils/coord_cython.pyx":115 - * cdef bint has_mask = mask is not None - * cdef np.int_t[:, :] m - * if has_mask: # <<<<<<<<<<<<<< - * m = np.array(mask, dtype=np.int_, copy=False, order='C') - * - */ - __pyx_t_12 = (__pyx_v_has_mask != 0); - if (__pyx_t_12) { - - /* "easyCore/Utils/coord_cython.pyx":116 - * cdef np.int_t[:, :] m - * if has_mask: - * m = np.array(mask, dtype=np.int_, copy=False, order='C') # <<<<<<<<<<<<<< - * - * cdef bint has_ftol = (lll_frac_tol is not None) - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_array); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_mask); - __Pyx_GIVEREF(__pyx_v_mask); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_mask); - __pyx_t_3 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_int); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 116, __pyx_L1_error) - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) __PYX_ERR(0, 116, __pyx_L1_error) - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_13 = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_int_t(__pyx_t_2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_13.memview)) __PYX_ERR(0, 116, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_v_m = __pyx_t_13; - __pyx_t_13.memview = NULL; - __pyx_t_13.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":115 - * cdef bint has_mask = mask is not None - * cdef np.int_t[:, :] m - * if has_mask: # <<<<<<<<<<<<<< - * m = np.array(mask, dtype=np.int_, copy=False, order='C') - * - */ - } - - /* "easyCore/Utils/coord_cython.pyx":118 - * m = np.array(mask, dtype=np.int_, copy=False, order='C') - * - * cdef bint has_ftol = (lll_frac_tol is not None) # <<<<<<<<<<<<<< - * cdef np.float_t[:] ftol - * if has_ftol: - */ - __pyx_t_12 = (__pyx_v_lll_frac_tol != Py_None); - __pyx_v_has_ftol = __pyx_t_12; - - /* "easyCore/Utils/coord_cython.pyx":120 - * cdef bint has_ftol = (lll_frac_tol is not None) - * cdef np.float_t[:] ftol - * if has_ftol: # <<<<<<<<<<<<<< - * ftol = np.array(lll_frac_tol, dtype=np.float_, order='C', copy=False) - * - */ - __pyx_t_12 = (__pyx_v_has_ftol != 0); - if (__pyx_t_12) { - - /* "easyCore/Utils/coord_cython.pyx":121 - * cdef np.float_t[:] ftol - * if has_ftol: - * ftol = np.array(lll_frac_tol, dtype=np.float_, order='C', copy=False) # <<<<<<<<<<<<<< - * - * - */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_array); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_v_lll_frac_tol); - __Pyx_GIVEREF(__pyx_v_lll_frac_tol); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_lll_frac_tol); - __pyx_t_1 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_np); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_float); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_order, __pyx_n_s_C) < 0) __PYX_ERR(0, 121, __pyx_L1_error) - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 121, __pyx_L1_error) - __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_14 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float_t(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_14.memview)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_v_ftol = __pyx_t_14; - __pyx_t_14.memview = NULL; - __pyx_t_14.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":120 - * cdef bint has_ftol = (lll_frac_tol is not None) - * cdef np.float_t[:] ftol - * if has_ftol: # <<<<<<<<<<<<<< - * ftol = np.array(lll_frac_tol, dtype=np.float_, order='C', copy=False) - * - */ - } - - /* "easyCore/Utils/coord_cython.pyx":124 - * - * - * dot_2d_mod(fc1, lat, cart_f1) # <<<<<<<<<<<<<< - * dot_2d_mod(fc2, lat, cart_f2) - * dot_2d(images_view, lat, cart_im) - */ - __pyx_f_8easyCore_5Utils_12coord_cython_dot_2d_mod(__pyx_v_fc1, __pyx_v_lat, __pyx_v_cart_f1); - - /* "easyCore/Utils/coord_cython.pyx":125 - * - * dot_2d_mod(fc1, lat, cart_f1) - * dot_2d_mod(fc2, lat, cart_f2) # <<<<<<<<<<<<<< - * dot_2d(images_view, lat, cart_im) - * - */ - __pyx_f_8easyCore_5Utils_12coord_cython_dot_2d_mod(__pyx_v_fc2, __pyx_v_lat, __pyx_v_cart_f2); - - /* "easyCore/Utils/coord_cython.pyx":126 - * dot_2d_mod(fc1, lat, cart_f1) - * dot_2d_mod(fc2, lat, cart_f2) - * dot_2d(images_view, lat, cart_im) # <<<<<<<<<<<<<< - * - * vectors = np.empty((I, J, 3)) - */ - __pyx_f_8easyCore_5Utils_12coord_cython_dot_2d(__pyx_v_8easyCore_5Utils_12coord_cython_images_view, __pyx_v_lat, __pyx_v_cart_im); - - /* "easyCore/Utils/coord_cython.pyx":128 - * dot_2d(images_view, lat, cart_im) - * - * vectors = np.empty((I, J, 3)) # <<<<<<<<<<<<<< - * d2 = np.empty((I, J)) - * cdef np.float_t[:, :, ::1] vs = vectors - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 128, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 128, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_I); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 128, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_J); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 128, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 128, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_3); - __Pyx_INCREF(__pyx_int_3); - __Pyx_GIVEREF(__pyx_int_3); - PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_int_3); - __pyx_t_1 = 0; - __pyx_t_3 = 0; - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_5 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_t_7) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_7); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 128, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_v_vectors = __pyx_t_5; - __pyx_t_5 = 0; - - /* "easyCore/Utils/coord_cython.pyx":129 - * - * vectors = np.empty((I, J, 3)) - * d2 = np.empty((I, J)) # <<<<<<<<<<<<<< - * cdef np.float_t[:, :, ::1] vs = vectors - * cdef np.float_t[:, ::1] ds = d2 - */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_I); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_J); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3); - __pyx_t_2 = 0; - __pyx_t_3 = 0; - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - } - } - __pyx_t_5 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_3, __pyx_t_1) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_v_d2 = __pyx_t_5; - __pyx_t_5 = 0; - - /* "easyCore/Utils/coord_cython.pyx":130 - * vectors = np.empty((I, J, 3)) - * d2 = np.empty((I, J)) - * cdef np.float_t[:, :, ::1] vs = vectors # <<<<<<<<<<<<<< - * cdef np.float_t[:, ::1] ds = d2 - * cdef np.float_t best, d, inc_d, da, db, dc, fdist - */ - __pyx_t_15 = __Pyx_PyObject_to_MemoryviewSlice_d_d_dc_nn___pyx_t_5numpy_float_t(__pyx_v_vectors, PyBUF_WRITABLE); if (unlikely(!__pyx_t_15.memview)) __PYX_ERR(0, 130, __pyx_L1_error) - __pyx_v_vs = __pyx_t_15; - __pyx_t_15.memview = NULL; - __pyx_t_15.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":131 - * d2 = np.empty((I, J)) - * cdef np.float_t[:, :, ::1] vs = vectors - * cdef np.float_t[:, ::1] ds = d2 # <<<<<<<<<<<<<< - * cdef np.float_t best, d, inc_d, da, db, dc, fdist - * cdef bint within_frac = True - */ - __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_float_t(__pyx_v_d2, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 131, __pyx_L1_error) - __pyx_v_ds = __pyx_t_8; - __pyx_t_8.memview = NULL; - __pyx_t_8.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":133 - * cdef np.float_t[:, ::1] ds = d2 - * cdef np.float_t best, d, inc_d, da, db, dc, fdist - * cdef bint within_frac = True # <<<<<<<<<<<<<< - * cdef np.float_t[:] pre_im = malloc(3 * sizeof(np.float_t)) - * - */ - __pyx_v_within_frac = 1; - - /* "easyCore/Utils/coord_cython.pyx":134 - * cdef np.float_t best, d, inc_d, da, db, dc, fdist - * cdef bint within_frac = True - * cdef np.float_t[:] pre_im = malloc(3 * sizeof(np.float_t)) # <<<<<<<<<<<<<< - * - * for i in range(I): - */ - __pyx_t_10 = malloc((3 * (sizeof(__pyx_t_5numpy_float_t)))); - if (!__pyx_t_10) { - PyErr_SetString(PyExc_ValueError,"Cannot create cython.array from NULL pointer"); - __PYX_ERR(0, 134, __pyx_L1_error) - } - __pyx_t_7 = __pyx_format_from_typeinfo(&__Pyx_TypeInfo_nn___pyx_t_5numpy_float_t); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 134, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_5 = Py_BuildValue((char*) "(" __PYX_BUILD_PY_SSIZE_T ")", ((Py_ssize_t)3)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 134, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_11 = __pyx_array_new(__pyx_t_5, sizeof(__pyx_t_5numpy_float_t), PyBytes_AS_STRING(__pyx_t_7), (char *) "c", (char *) __pyx_t_10); - if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 134, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_t_14 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float_t(((PyObject *)__pyx_t_11), PyBUF_WRITABLE); if (unlikely(!__pyx_t_14.memview)) __PYX_ERR(0, 134, __pyx_L1_error) - __Pyx_DECREF(((PyObject *)__pyx_t_11)); __pyx_t_11 = 0; - __pyx_v_pre_im = __pyx_t_14; - __pyx_t_14.memview = NULL; - __pyx_t_14.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":136 - * cdef np.float_t[:] pre_im = malloc(3 * sizeof(np.float_t)) - * - * for i in range(I): # <<<<<<<<<<<<<< - * for j in range(J): - * within_frac = False - */ - __pyx_t_4 = __pyx_v_I; - __pyx_t_16 = __pyx_t_4; - for (__pyx_t_17 = 0; __pyx_t_17 < __pyx_t_16; __pyx_t_17+=1) { - __pyx_v_i = __pyx_t_17; - - /* "easyCore/Utils/coord_cython.pyx":137 - * - * for i in range(I): - * for j in range(J): # <<<<<<<<<<<<<< - * within_frac = False - * if (not has_mask) or (m[i, j] == 0): - */ - __pyx_t_18 = __pyx_v_J; - __pyx_t_19 = __pyx_t_18; - for (__pyx_t_20 = 0; __pyx_t_20 < __pyx_t_19; __pyx_t_20+=1) { - __pyx_v_j = __pyx_t_20; - - /* "easyCore/Utils/coord_cython.pyx":138 - * for i in range(I): - * for j in range(J): - * within_frac = False # <<<<<<<<<<<<<< - * if (not has_mask) or (m[i, j] == 0): - * within_frac = True - */ - __pyx_v_within_frac = 0; - - /* "easyCore/Utils/coord_cython.pyx":139 - * for j in range(J): - * within_frac = False - * if (not has_mask) or (m[i, j] == 0): # <<<<<<<<<<<<<< - * within_frac = True - * if has_ftol: - */ - __pyx_t_21 = ((!(__pyx_v_has_mask != 0)) != 0); - if (!__pyx_t_21) { - } else { - __pyx_t_12 = __pyx_t_21; - goto __pyx_L12_bool_binop_done; - } - __pyx_t_22 = __pyx_v_i; - __pyx_t_23 = __pyx_v_j; - __pyx_t_21 = (((*((__pyx_t_5numpy_int_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_m.data + __pyx_t_22 * __pyx_v_m.strides[0]) ) + __pyx_t_23 * __pyx_v_m.strides[1]) ))) == 0) != 0); - __pyx_t_12 = __pyx_t_21; - __pyx_L12_bool_binop_done:; - if (__pyx_t_12) { - - /* "easyCore/Utils/coord_cython.pyx":140 - * within_frac = False - * if (not has_mask) or (m[i, j] == 0): - * within_frac = True # <<<<<<<<<<<<<< - * if has_ftol: - * for l in range(3): - */ - __pyx_v_within_frac = 1; - - /* "easyCore/Utils/coord_cython.pyx":141 - * if (not has_mask) or (m[i, j] == 0): - * within_frac = True - * if has_ftol: # <<<<<<<<<<<<<< - * for l in range(3): - * fdist = fc2[j, l] - fc1[i, l] - */ - __pyx_t_12 = (__pyx_v_has_ftol != 0); - if (__pyx_t_12) { - - /* "easyCore/Utils/coord_cython.pyx":142 - * within_frac = True - * if has_ftol: - * for l in range(3): # <<<<<<<<<<<<<< - * fdist = fc2[j, l] - fc1[i, l] - * if fabs(fdist - round(fdist)) > ftol[l]: - */ - for (__pyx_t_24 = 0; __pyx_t_24 < 3; __pyx_t_24+=1) { - __pyx_v_l = __pyx_t_24; - - /* "easyCore/Utils/coord_cython.pyx":143 - * if has_ftol: - * for l in range(3): - * fdist = fc2[j, l] - fc1[i, l] # <<<<<<<<<<<<<< - * if fabs(fdist - round(fdist)) > ftol[l]: - * within_frac = False - */ - __pyx_t_23 = __pyx_v_j; - __pyx_t_22 = __pyx_v_l; - __pyx_t_25 = __pyx_v_i; - __pyx_t_26 = __pyx_v_l; - __pyx_v_fdist = ((*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_fc2.data + __pyx_t_23 * __pyx_v_fc2.strides[0]) )) + __pyx_t_22)) ))) - (*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_fc1.data + __pyx_t_25 * __pyx_v_fc1.strides[0]) )) + __pyx_t_26)) )))); - - /* "easyCore/Utils/coord_cython.pyx":144 - * for l in range(3): - * fdist = fc2[j, l] - fc1[i, l] - * if fabs(fdist - round(fdist)) > ftol[l]: # <<<<<<<<<<<<<< - * within_frac = False - * break - */ - __pyx_t_26 = __pyx_v_l; - __pyx_t_12 = ((fabs((__pyx_v_fdist - round(__pyx_v_fdist))) > (*((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_ftol.data + __pyx_t_26 * __pyx_v_ftol.strides[0]) )))) != 0); - if (__pyx_t_12) { - - /* "easyCore/Utils/coord_cython.pyx":145 - * fdist = fc2[j, l] - fc1[i, l] - * if fabs(fdist - round(fdist)) > ftol[l]: - * within_frac = False # <<<<<<<<<<<<<< - * break - * if within_frac: - */ - __pyx_v_within_frac = 0; - - /* "easyCore/Utils/coord_cython.pyx":146 - * if fabs(fdist - round(fdist)) > ftol[l]: - * within_frac = False - * break # <<<<<<<<<<<<<< - * if within_frac: - * for l in range(3): - */ - goto __pyx_L16_break; - - /* "easyCore/Utils/coord_cython.pyx":144 - * for l in range(3): - * fdist = fc2[j, l] - fc1[i, l] - * if fabs(fdist - round(fdist)) > ftol[l]: # <<<<<<<<<<<<<< - * within_frac = False - * break - */ - } - } - __pyx_L16_break:; - - /* "easyCore/Utils/coord_cython.pyx":141 - * if (not has_mask) or (m[i, j] == 0): - * within_frac = True - * if has_ftol: # <<<<<<<<<<<<<< - * for l in range(3): - * fdist = fc2[j, l] - fc1[i, l] - */ - } - - /* "easyCore/Utils/coord_cython.pyx":147 - * within_frac = False - * break - * if within_frac: # <<<<<<<<<<<<<< - * for l in range(3): - * pre_im[l] = cart_f2[j, l] - cart_f1[i, l] - */ - __pyx_t_12 = (__pyx_v_within_frac != 0); - if (__pyx_t_12) { - - /* "easyCore/Utils/coord_cython.pyx":148 - * break - * if within_frac: - * for l in range(3): # <<<<<<<<<<<<<< - * pre_im[l] = cart_f2[j, l] - cart_f1[i, l] - * best = 1e100 - */ - for (__pyx_t_24 = 0; __pyx_t_24 < 3; __pyx_t_24+=1) { - __pyx_v_l = __pyx_t_24; - - /* "easyCore/Utils/coord_cython.pyx":149 - * if within_frac: - * for l in range(3): - * pre_im[l] = cart_f2[j, l] - cart_f1[i, l] # <<<<<<<<<<<<<< - * best = 1e100 - * for k in range(27): - */ - __pyx_t_26 = __pyx_v_j; - __pyx_t_25 = __pyx_v_l; - __pyx_t_22 = __pyx_v_i; - __pyx_t_23 = __pyx_v_l; - __pyx_t_27 = __pyx_v_l; - *((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_pre_im.data + __pyx_t_27 * __pyx_v_pre_im.strides[0]) )) = ((*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_cart_f2.data + __pyx_t_26 * __pyx_v_cart_f2.strides[0]) )) + __pyx_t_25)) ))) - (*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_cart_f1.data + __pyx_t_22 * __pyx_v_cart_f1.strides[0]) )) + __pyx_t_23)) )))); - } - - /* "easyCore/Utils/coord_cython.pyx":150 - * for l in range(3): - * pre_im[l] = cart_f2[j, l] - cart_f1[i, l] - * best = 1e100 # <<<<<<<<<<<<<< - * for k in range(27): - * # compilers have a hard time unrolling this - */ - __pyx_v_best = 1e100; - - /* "easyCore/Utils/coord_cython.pyx":151 - * pre_im[l] = cart_f2[j, l] - cart_f1[i, l] - * best = 1e100 - * for k in range(27): # <<<<<<<<<<<<<< - * # compilers have a hard time unrolling this - * da = pre_im[0] + cart_im[k, 0] - */ - for (__pyx_t_24 = 0; __pyx_t_24 < 27; __pyx_t_24+=1) { - __pyx_v_k = __pyx_t_24; - - /* "easyCore/Utils/coord_cython.pyx":153 - * for k in range(27): - * # compilers have a hard time unrolling this - * da = pre_im[0] + cart_im[k, 0] # <<<<<<<<<<<<<< - * db = pre_im[1] + cart_im[k, 1] - * dc = pre_im[2] + cart_im[k, 2] - */ - __pyx_t_23 = 0; - __pyx_t_22 = __pyx_v_k; - __pyx_t_25 = 0; - __pyx_v_da = ((*((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_pre_im.data + __pyx_t_23 * __pyx_v_pre_im.strides[0]) ))) + (*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_cart_im.data + __pyx_t_22 * __pyx_v_cart_im.strides[0]) )) + __pyx_t_25)) )))); - - /* "easyCore/Utils/coord_cython.pyx":154 - * # compilers have a hard time unrolling this - * da = pre_im[0] + cart_im[k, 0] - * db = pre_im[1] + cart_im[k, 1] # <<<<<<<<<<<<<< - * dc = pre_im[2] + cart_im[k, 2] - * d = da * da + db * db + dc * dc - */ - __pyx_t_25 = 1; - __pyx_t_22 = __pyx_v_k; - __pyx_t_23 = 1; - __pyx_v_db = ((*((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_pre_im.data + __pyx_t_25 * __pyx_v_pre_im.strides[0]) ))) + (*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_cart_im.data + __pyx_t_22 * __pyx_v_cart_im.strides[0]) )) + __pyx_t_23)) )))); - - /* "easyCore/Utils/coord_cython.pyx":155 - * da = pre_im[0] + cart_im[k, 0] - * db = pre_im[1] + cart_im[k, 1] - * dc = pre_im[2] + cart_im[k, 2] # <<<<<<<<<<<<<< - * d = da * da + db * db + dc * dc - * if d < best: - */ - __pyx_t_23 = 2; - __pyx_t_22 = __pyx_v_k; - __pyx_t_25 = 2; - __pyx_v_dc = ((*((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_pre_im.data + __pyx_t_23 * __pyx_v_pre_im.strides[0]) ))) + (*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_cart_im.data + __pyx_t_22 * __pyx_v_cart_im.strides[0]) )) + __pyx_t_25)) )))); - - /* "easyCore/Utils/coord_cython.pyx":156 - * db = pre_im[1] + cart_im[k, 1] - * dc = pre_im[2] + cart_im[k, 2] - * d = da * da + db * db + dc * dc # <<<<<<<<<<<<<< - * if d < best: - * best = d - */ - __pyx_v_d = (((__pyx_v_da * __pyx_v_da) + (__pyx_v_db * __pyx_v_db)) + (__pyx_v_dc * __pyx_v_dc)); - - /* "easyCore/Utils/coord_cython.pyx":157 - * dc = pre_im[2] + cart_im[k, 2] - * d = da * da + db * db + dc * dc - * if d < best: # <<<<<<<<<<<<<< - * best = d - * bestk = k - */ - __pyx_t_12 = ((__pyx_v_d < __pyx_v_best) != 0); - if (__pyx_t_12) { - - /* "easyCore/Utils/coord_cython.pyx":158 - * d = da * da + db * db + dc * dc - * if d < best: - * best = d # <<<<<<<<<<<<<< - * bestk = k - * ds[i, j] = best - */ - __pyx_v_best = __pyx_v_d; - - /* "easyCore/Utils/coord_cython.pyx":159 - * if d < best: - * best = d - * bestk = k # <<<<<<<<<<<<<< - * ds[i, j] = best - * for l in range(3): - */ - __pyx_v_bestk = __pyx_v_k; - - /* "easyCore/Utils/coord_cython.pyx":157 - * dc = pre_im[2] + cart_im[k, 2] - * d = da * da + db * db + dc * dc - * if d < best: # <<<<<<<<<<<<<< - * best = d - * bestk = k - */ - } - } - - /* "easyCore/Utils/coord_cython.pyx":160 - * best = d - * bestk = k - * ds[i, j] = best # <<<<<<<<<<<<<< - * for l in range(3): - * vs[i, j, l] = pre_im[l] + cart_im[bestk, l] - */ - __pyx_t_25 = __pyx_v_i; - __pyx_t_22 = __pyx_v_j; - *((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_ds.data + __pyx_t_25 * __pyx_v_ds.strides[0]) )) + __pyx_t_22)) )) = __pyx_v_best; - - /* "easyCore/Utils/coord_cython.pyx":161 - * bestk = k - * ds[i, j] = best - * for l in range(3): # <<<<<<<<<<<<<< - * vs[i, j, l] = pre_im[l] + cart_im[bestk, l] - * if not within_frac: - */ - for (__pyx_t_24 = 0; __pyx_t_24 < 3; __pyx_t_24+=1) { - __pyx_v_l = __pyx_t_24; - - /* "easyCore/Utils/coord_cython.pyx":162 - * ds[i, j] = best - * for l in range(3): - * vs[i, j, l] = pre_im[l] + cart_im[bestk, l] # <<<<<<<<<<<<<< - * if not within_frac: - * ds[i, j] = 1e20 - */ - __pyx_t_22 = __pyx_v_l; - __pyx_t_25 = __pyx_v_bestk; - __pyx_t_23 = __pyx_v_l; - __pyx_t_26 = __pyx_v_i; - __pyx_t_27 = __pyx_v_j; - __pyx_t_28 = __pyx_v_l; - *((__pyx_t_5numpy_float_t *) ( /* dim=2 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_vs.data + __pyx_t_26 * __pyx_v_vs.strides[0]) ) + __pyx_t_27 * __pyx_v_vs.strides[1]) )) + __pyx_t_28)) )) = ((*((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_pre_im.data + __pyx_t_22 * __pyx_v_pre_im.strides[0]) ))) + (*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_cart_im.data + __pyx_t_25 * __pyx_v_cart_im.strides[0]) )) + __pyx_t_23)) )))); - } - - /* "easyCore/Utils/coord_cython.pyx":147 - * within_frac = False - * break - * if within_frac: # <<<<<<<<<<<<<< - * for l in range(3): - * pre_im[l] = cart_f2[j, l] - cart_f1[i, l] - */ - } - - /* "easyCore/Utils/coord_cython.pyx":139 - * for j in range(J): - * within_frac = False - * if (not has_mask) or (m[i, j] == 0): # <<<<<<<<<<<<<< - * within_frac = True - * if has_ftol: - */ - } - - /* "easyCore/Utils/coord_cython.pyx":163 - * for l in range(3): - * vs[i, j, l] = pre_im[l] + cart_im[bestk, l] - * if not within_frac: # <<<<<<<<<<<<<< - * ds[i, j] = 1e20 - * for l in range(3): - */ - __pyx_t_12 = ((!(__pyx_v_within_frac != 0)) != 0); - if (__pyx_t_12) { - - /* "easyCore/Utils/coord_cython.pyx":164 - * vs[i, j, l] = pre_im[l] + cart_im[bestk, l] - * if not within_frac: - * ds[i, j] = 1e20 # <<<<<<<<<<<<<< - * for l in range(3): - * vs[i, j, l] = 1e20 - */ - __pyx_t_23 = __pyx_v_i; - __pyx_t_25 = __pyx_v_j; - *((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_ds.data + __pyx_t_23 * __pyx_v_ds.strides[0]) )) + __pyx_t_25)) )) = 1e20; - - /* "easyCore/Utils/coord_cython.pyx":165 - * if not within_frac: - * ds[i, j] = 1e20 - * for l in range(3): # <<<<<<<<<<<<<< - * vs[i, j, l] = 1e20 - * - */ - for (__pyx_t_24 = 0; __pyx_t_24 < 3; __pyx_t_24+=1) { - __pyx_v_l = __pyx_t_24; - - /* "easyCore/Utils/coord_cython.pyx":166 - * ds[i, j] = 1e20 - * for l in range(3): - * vs[i, j, l] = 1e20 # <<<<<<<<<<<<<< - * - * free(&cart_f1[0,0]) - */ - __pyx_t_25 = __pyx_v_i; - __pyx_t_23 = __pyx_v_j; - __pyx_t_22 = __pyx_v_l; - *((__pyx_t_5numpy_float_t *) ( /* dim=2 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_vs.data + __pyx_t_25 * __pyx_v_vs.strides[0]) ) + __pyx_t_23 * __pyx_v_vs.strides[1]) )) + __pyx_t_22)) )) = 1e20; - } - - /* "easyCore/Utils/coord_cython.pyx":163 - * for l in range(3): - * vs[i, j, l] = pre_im[l] + cart_im[bestk, l] - * if not within_frac: # <<<<<<<<<<<<<< - * ds[i, j] = 1e20 - * for l in range(3): - */ - } - } - } - - /* "easyCore/Utils/coord_cython.pyx":168 - * vs[i, j, l] = 1e20 - * - * free(&cart_f1[0,0]) # <<<<<<<<<<<<<< - * free(&cart_f2[0,0]) - * free(&cart_im[0,0]) - */ - __pyx_t_22 = 0; - __pyx_t_23 = 0; - free((&(*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_cart_f1.data + __pyx_t_22 * __pyx_v_cart_f1.strides[0]) )) + __pyx_t_23)) ))))); - - /* "easyCore/Utils/coord_cython.pyx":169 - * - * free(&cart_f1[0,0]) - * free(&cart_f2[0,0]) # <<<<<<<<<<<<<< - * free(&cart_im[0,0]) - * free(&pre_im[0]) - */ - __pyx_t_23 = 0; - __pyx_t_22 = 0; - free((&(*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_cart_f2.data + __pyx_t_23 * __pyx_v_cart_f2.strides[0]) )) + __pyx_t_22)) ))))); - - /* "easyCore/Utils/coord_cython.pyx":170 - * free(&cart_f1[0,0]) - * free(&cart_f2[0,0]) - * free(&cart_im[0,0]) # <<<<<<<<<<<<<< - * free(&pre_im[0]) - * - */ - __pyx_t_22 = 0; - __pyx_t_23 = 0; - free((&(*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_cart_im.data + __pyx_t_22 * __pyx_v_cart_im.strides[0]) )) + __pyx_t_23)) ))))); - - /* "easyCore/Utils/coord_cython.pyx":171 - * free(&cart_f2[0,0]) - * free(&cart_im[0,0]) - * free(&pre_im[0]) # <<<<<<<<<<<<<< - * - * if return_d2: - */ - __pyx_t_23 = 0; - free((&(*((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_pre_im.data + __pyx_t_23 * __pyx_v_pre_im.strides[0]) ))))); - - /* "easyCore/Utils/coord_cython.pyx":173 - * free(&pre_im[0]) - * - * if return_d2: # <<<<<<<<<<<<<< - * return vectors, d2 - * else: - */ - __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_v_return_d2); if (unlikely(__pyx_t_12 < 0)) __PYX_ERR(0, 173, __pyx_L1_error) - if (__pyx_t_12) { - - /* "easyCore/Utils/coord_cython.pyx":174 - * - * if return_d2: - * return vectors, d2 # <<<<<<<<<<<<<< - * else: - * return vectors - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 174, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_INCREF(__pyx_v_vectors); - __Pyx_GIVEREF(__pyx_v_vectors); - PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_vectors); - __Pyx_INCREF(__pyx_v_d2); - __Pyx_GIVEREF(__pyx_v_d2); - PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_v_d2); - __pyx_r = __pyx_t_7; - __pyx_t_7 = 0; - goto __pyx_L0; - - /* "easyCore/Utils/coord_cython.pyx":173 - * free(&pre_im[0]) - * - * if return_d2: # <<<<<<<<<<<<<< - * return vectors, d2 - * else: - */ - } - - /* "easyCore/Utils/coord_cython.pyx":176 - * return vectors, d2 - * else: - * return vectors # <<<<<<<<<<<<<< - * - * @cython.boundscheck(False) - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_vectors); - __pyx_r = __pyx_v_vectors; - goto __pyx_L0; - } - - /* "easyCore/Utils/coord_cython.pyx":70 - * @cython.wraparound(False) - * @cython.initializedcheck(False) - * def pbc_shortest_vectors(lattice, fcoords1, fcoords2, mask=None, return_d2=False, lll_frac_tol=None): # <<<<<<<<<<<<<< - * """ - * Returns the shortest vectors between two lists of coordinates taking into - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_7); - __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1); - __Pyx_XDECREF(((PyObject *)__pyx_t_11)); - __PYX_XDEC_MEMVIEW(&__pyx_t_13, 1); - __PYX_XDEC_MEMVIEW(&__pyx_t_14, 1); - __PYX_XDEC_MEMVIEW(&__pyx_t_15, 1); - __Pyx_AddTraceback("easyCore.Utils.coord_cython.pbc_shortest_vectors", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __PYX_XDEC_MEMVIEW(&__pyx_v_lat, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_fc1, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_fc2, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_cart_f1, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_cart_f2, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_cart_im, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_m, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_ftol, 1); - __Pyx_XDECREF(__pyx_v_vectors); - __Pyx_XDECREF(__pyx_v_d2); - __PYX_XDEC_MEMVIEW(&__pyx_v_vs, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_ds, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_pre_im, 1); - __Pyx_XDECREF(__pyx_v_fcoords1); - __Pyx_XDECREF(__pyx_v_fcoords2); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "easyCore/Utils/coord_cython.pyx":181 - * @cython.wraparound(False) - * @cython.initializedcheck(False) - * def is_coord_subset_pbc(subset, superset, atol, mask): # <<<<<<<<<<<<<< - * """ - * Tests if all fractional coords in subset are contained in superset. - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_8easyCore_5Utils_12coord_cython_3is_coord_subset_pbc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_8easyCore_5Utils_12coord_cython_2is_coord_subset_pbc[] = "\n Tests if all fractional coords in subset are contained in superset.\n Allows specification of a mask determining pairs that are not\n allowed to match to each other\n\n Args:\n subset, superset: List of fractional coords\n\n Returns:\n True if all of subset is in superset.\n "; -static PyMethodDef __pyx_mdef_8easyCore_5Utils_12coord_cython_3is_coord_subset_pbc = {"is_coord_subset_pbc", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8easyCore_5Utils_12coord_cython_3is_coord_subset_pbc, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8easyCore_5Utils_12coord_cython_2is_coord_subset_pbc}; -static PyObject *__pyx_pw_8easyCore_5Utils_12coord_cython_3is_coord_subset_pbc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_subset = 0; - PyObject *__pyx_v_superset = 0; - PyObject *__pyx_v_atol = 0; - PyObject *__pyx_v_mask = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("is_coord_subset_pbc (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_subset,&__pyx_n_s_superset,&__pyx_n_s_atol,&__pyx_n_s_mask,0}; - PyObject* values[4] = {0,0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_subset)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_superset)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("is_coord_subset_pbc", 1, 4, 4, 1); __PYX_ERR(0, 181, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_atol)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("is_coord_subset_pbc", 1, 4, 4, 2); __PYX_ERR(0, 181, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("is_coord_subset_pbc", 1, 4, 4, 3); __PYX_ERR(0, 181, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "is_coord_subset_pbc") < 0)) __PYX_ERR(0, 181, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 4) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - } - __pyx_v_subset = values[0]; - __pyx_v_superset = values[1]; - __pyx_v_atol = values[2]; - __pyx_v_mask = values[3]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("is_coord_subset_pbc", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 181, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("easyCore.Utils.coord_cython.is_coord_subset_pbc", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_8easyCore_5Utils_12coord_cython_2is_coord_subset_pbc(__pyx_self, __pyx_v_subset, __pyx_v_superset, __pyx_v_atol, __pyx_v_mask); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_8easyCore_5Utils_12coord_cython_2is_coord_subset_pbc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_subset, PyObject *__pyx_v_superset, PyObject *__pyx_v_atol, PyObject *__pyx_v_mask) { - __Pyx_memviewslice __pyx_v_fc1 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_fc2 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_t = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_m = { 0, 0, { 0 }, { 0 }, { 0 } }; - int __pyx_v_i; - int __pyx_v_j; - int __pyx_v_k; - int __pyx_v_I; - int __pyx_v_J; - __pyx_t_5numpy_float_t __pyx_v_d; - int __pyx_v_ok; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice __pyx_t_1 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_t_2 = { 0, 0, { 0 }, { 0 }, { 0 } }; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } }; - int __pyx_t_9; - int __pyx_t_10; - int __pyx_t_11; - int __pyx_t_12; - int __pyx_t_13; - int __pyx_t_14; - Py_ssize_t __pyx_t_15; - Py_ssize_t __pyx_t_16; - int __pyx_t_17; - int __pyx_t_18; - Py_ssize_t __pyx_t_19; - Py_ssize_t __pyx_t_20; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("is_coord_subset_pbc", 0); - - /* "easyCore/Utils/coord_cython.pyx":194 - * """ - * - * cdef np.float_t[:, :] fc1 = subset # <<<<<<<<<<<<<< - * cdef np.float_t[:, :] fc2 = superset - * cdef np.float_t[:] t = atol - */ - __pyx_t_1 = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_float_t(__pyx_v_subset, PyBUF_WRITABLE); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 194, __pyx_L1_error) - __pyx_v_fc1 = __pyx_t_1; - __pyx_t_1.memview = NULL; - __pyx_t_1.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":195 - * - * cdef np.float_t[:, :] fc1 = subset - * cdef np.float_t[:, :] fc2 = superset # <<<<<<<<<<<<<< - * cdef np.float_t[:] t = atol - * cdef np.int_t[:, :] m = np.array(mask, dtype=np.int_, copy=False, order='C') - */ - __pyx_t_1 = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_float_t(__pyx_v_superset, PyBUF_WRITABLE); if (unlikely(!__pyx_t_1.memview)) __PYX_ERR(0, 195, __pyx_L1_error) - __pyx_v_fc2 = __pyx_t_1; - __pyx_t_1.memview = NULL; - __pyx_t_1.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":196 - * cdef np.float_t[:, :] fc1 = subset - * cdef np.float_t[:, :] fc2 = superset - * cdef np.float_t[:] t = atol # <<<<<<<<<<<<<< - * cdef np.int_t[:, :] m = np.array(mask, dtype=np.int_, copy=False, order='C') - * - */ - __pyx_t_2 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float_t(__pyx_v_atol, PyBUF_WRITABLE); if (unlikely(!__pyx_t_2.memview)) __PYX_ERR(0, 196, __pyx_L1_error) - __pyx_v_t = __pyx_t_2; - __pyx_t_2.memview = NULL; - __pyx_t_2.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":197 - * cdef np.float_t[:, :] fc2 = superset - * cdef np.float_t[:] t = atol - * cdef np.int_t[:, :] m = np.array(mask, dtype=np.int_, copy=False, order='C') # <<<<<<<<<<<<<< - * - * cdef int i, j, k, I, J - */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 197, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 197, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 197, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_mask); - __Pyx_GIVEREF(__pyx_v_mask); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_mask); - __pyx_t_5 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 197, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_np); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 197, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_int); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 197, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) __PYX_ERR(0, 197, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 197, __pyx_L1_error) - if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) __PYX_ERR(0, 197, __pyx_L1_error) - __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 197, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_int_t(__pyx_t_7, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 197, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_v_m = __pyx_t_8; - __pyx_t_8.memview = NULL; - __pyx_t_8.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":203 - * cdef bint ok - * - * I = fc1.shape[0] # <<<<<<<<<<<<<< - * J = fc2.shape[0] - * - */ - __pyx_v_I = (__pyx_v_fc1.shape[0]); - - /* "easyCore/Utils/coord_cython.pyx":204 - * - * I = fc1.shape[0] - * J = fc2.shape[0] # <<<<<<<<<<<<<< - * - * for i in range(I): - */ - __pyx_v_J = (__pyx_v_fc2.shape[0]); - - /* "easyCore/Utils/coord_cython.pyx":206 - * J = fc2.shape[0] - * - * for i in range(I): # <<<<<<<<<<<<<< - * ok = False - * for j in range(J): - */ - __pyx_t_9 = __pyx_v_I; - __pyx_t_10 = __pyx_t_9; - for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) { - __pyx_v_i = __pyx_t_11; - - /* "easyCore/Utils/coord_cython.pyx":207 - * - * for i in range(I): - * ok = False # <<<<<<<<<<<<<< - * for j in range(J): - * if m[i, j]: - */ - __pyx_v_ok = 0; - - /* "easyCore/Utils/coord_cython.pyx":208 - * for i in range(I): - * ok = False - * for j in range(J): # <<<<<<<<<<<<<< - * if m[i, j]: - * continue - */ - __pyx_t_12 = __pyx_v_J; - __pyx_t_13 = __pyx_t_12; - for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) { - __pyx_v_j = __pyx_t_14; - - /* "easyCore/Utils/coord_cython.pyx":209 - * ok = False - * for j in range(J): - * if m[i, j]: # <<<<<<<<<<<<<< - * continue - * ok = True - */ - __pyx_t_15 = __pyx_v_i; - __pyx_t_16 = __pyx_v_j; - __pyx_t_17 = ((*((__pyx_t_5numpy_int_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_m.data + __pyx_t_15 * __pyx_v_m.strides[0]) ) + __pyx_t_16 * __pyx_v_m.strides[1]) ))) != 0); - if (__pyx_t_17) { - - /* "easyCore/Utils/coord_cython.pyx":210 - * for j in range(J): - * if m[i, j]: - * continue # <<<<<<<<<<<<<< - * ok = True - * for k in range(3): - */ - goto __pyx_L5_continue; - - /* "easyCore/Utils/coord_cython.pyx":209 - * ok = False - * for j in range(J): - * if m[i, j]: # <<<<<<<<<<<<<< - * continue - * ok = True - */ - } - - /* "easyCore/Utils/coord_cython.pyx":211 - * if m[i, j]: - * continue - * ok = True # <<<<<<<<<<<<<< - * for k in range(3): - * d = fc1[i, k] - fc2[j, k] - */ - __pyx_v_ok = 1; - - /* "easyCore/Utils/coord_cython.pyx":212 - * continue - * ok = True - * for k in range(3): # <<<<<<<<<<<<<< - * d = fc1[i, k] - fc2[j, k] - * if fabs(d - round(d)) > t[k]: - */ - for (__pyx_t_18 = 0; __pyx_t_18 < 3; __pyx_t_18+=1) { - __pyx_v_k = __pyx_t_18; - - /* "easyCore/Utils/coord_cython.pyx":213 - * ok = True - * for k in range(3): - * d = fc1[i, k] - fc2[j, k] # <<<<<<<<<<<<<< - * if fabs(d - round(d)) > t[k]: - * ok = False - */ - __pyx_t_16 = __pyx_v_i; - __pyx_t_15 = __pyx_v_k; - __pyx_t_19 = __pyx_v_j; - __pyx_t_20 = __pyx_v_k; - __pyx_v_d = ((*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fc1.data + __pyx_t_16 * __pyx_v_fc1.strides[0]) ) + __pyx_t_15 * __pyx_v_fc1.strides[1]) ))) - (*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fc2.data + __pyx_t_19 * __pyx_v_fc2.strides[0]) ) + __pyx_t_20 * __pyx_v_fc2.strides[1]) )))); - - /* "easyCore/Utils/coord_cython.pyx":214 - * for k in range(3): - * d = fc1[i, k] - fc2[j, k] - * if fabs(d - round(d)) > t[k]: # <<<<<<<<<<<<<< - * ok = False - * break - */ - __pyx_t_20 = __pyx_v_k; - __pyx_t_17 = ((fabs((__pyx_v_d - round(__pyx_v_d))) > (*((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_t.data + __pyx_t_20 * __pyx_v_t.strides[0]) )))) != 0); - if (__pyx_t_17) { - - /* "easyCore/Utils/coord_cython.pyx":215 - * d = fc1[i, k] - fc2[j, k] - * if fabs(d - round(d)) > t[k]: - * ok = False # <<<<<<<<<<<<<< - * break - * if ok: - */ - __pyx_v_ok = 0; - - /* "easyCore/Utils/coord_cython.pyx":216 - * if fabs(d - round(d)) > t[k]: - * ok = False - * break # <<<<<<<<<<<<<< - * if ok: - * break - */ - goto __pyx_L9_break; - - /* "easyCore/Utils/coord_cython.pyx":214 - * for k in range(3): - * d = fc1[i, k] - fc2[j, k] - * if fabs(d - round(d)) > t[k]: # <<<<<<<<<<<<<< - * ok = False - * break - */ - } - } - __pyx_L9_break:; - - /* "easyCore/Utils/coord_cython.pyx":217 - * ok = False - * break - * if ok: # <<<<<<<<<<<<<< - * break - * if not ok: - */ - __pyx_t_17 = (__pyx_v_ok != 0); - if (__pyx_t_17) { - - /* "easyCore/Utils/coord_cython.pyx":218 - * break - * if ok: - * break # <<<<<<<<<<<<<< - * if not ok: - * break - */ - goto __pyx_L6_break; - - /* "easyCore/Utils/coord_cython.pyx":217 - * ok = False - * break - * if ok: # <<<<<<<<<<<<<< - * break - * if not ok: - */ - } - __pyx_L5_continue:; - } - __pyx_L6_break:; - - /* "easyCore/Utils/coord_cython.pyx":219 - * if ok: - * break - * if not ok: # <<<<<<<<<<<<<< - * break - * return bool(ok) - */ - __pyx_t_17 = ((!(__pyx_v_ok != 0)) != 0); - if (__pyx_t_17) { - - /* "easyCore/Utils/coord_cython.pyx":220 - * break - * if not ok: - * break # <<<<<<<<<<<<<< - * return bool(ok) - * - */ - goto __pyx_L4_break; - - /* "easyCore/Utils/coord_cython.pyx":219 - * if ok: - * break - * if not ok: # <<<<<<<<<<<<<< - * break - * return bool(ok) - */ - } - } - __pyx_L4_break:; - - /* "easyCore/Utils/coord_cython.pyx":221 - * if not ok: - * break - * return bool(ok) # <<<<<<<<<<<<<< - * - * @cython.boundscheck(False) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_17 = __pyx_v_ok; - __pyx_t_7 = __Pyx_PyBool_FromLong((!(!__pyx_t_17))); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 221, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_r = __pyx_t_7; - __pyx_t_7 = 0; - goto __pyx_L0; - - /* "easyCore/Utils/coord_cython.pyx":181 - * @cython.wraparound(False) - * @cython.initializedcheck(False) - * def is_coord_subset_pbc(subset, superset, atol, mask): # <<<<<<<<<<<<<< - * """ - * Tests if all fractional coords in subset are contained in superset. - */ - - /* function exit code */ - __pyx_L1_error:; - __PYX_XDEC_MEMVIEW(&__pyx_t_1, 1); - __PYX_XDEC_MEMVIEW(&__pyx_t_2, 1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1); - __Pyx_AddTraceback("easyCore.Utils.coord_cython.is_coord_subset_pbc", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __PYX_XDEC_MEMVIEW(&__pyx_v_fc1, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_fc2, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_t, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_m, 1); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "easyCore/Utils/coord_cython.pyx":226 - * @cython.wraparound(False) - * @cython.initializedcheck(False) - * def coord_list_mapping_pbc(subset, superset, atol=1e-8): # <<<<<<<<<<<<<< - * """ - * Gives the index mapping from a subset to a superset. - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_8easyCore_5Utils_12coord_cython_5coord_list_mapping_pbc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_8easyCore_5Utils_12coord_cython_4coord_list_mapping_pbc[] = "\n Gives the index mapping from a subset to a superset.\n Superset cannot contain duplicate matching rows\n\n Args:\n subset, superset: List of frac_coords\n\n Returns:\n list of indices such that superset[indices] = subset\n "; -static PyMethodDef __pyx_mdef_8easyCore_5Utils_12coord_cython_5coord_list_mapping_pbc = {"coord_list_mapping_pbc", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_8easyCore_5Utils_12coord_cython_5coord_list_mapping_pbc, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8easyCore_5Utils_12coord_cython_4coord_list_mapping_pbc}; -static PyObject *__pyx_pw_8easyCore_5Utils_12coord_cython_5coord_list_mapping_pbc(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_subset = 0; - PyObject *__pyx_v_superset = 0; - PyObject *__pyx_v_atol = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("coord_list_mapping_pbc (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_subset,&__pyx_n_s_superset,&__pyx_n_s_atol,0}; - PyObject* values[3] = {0,0,0}; - values[2] = ((PyObject *)__pyx_float_1eneg_8); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_subset)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_superset)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("coord_list_mapping_pbc", 0, 2, 3, 1); __PYX_ERR(0, 226, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_atol); - if (value) { values[2] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "coord_list_mapping_pbc") < 0)) __PYX_ERR(0, 226, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_subset = values[0]; - __pyx_v_superset = values[1]; - __pyx_v_atol = values[2]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("coord_list_mapping_pbc", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 226, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("easyCore.Utils.coord_cython.coord_list_mapping_pbc", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_8easyCore_5Utils_12coord_cython_4coord_list_mapping_pbc(__pyx_self, __pyx_v_subset, __pyx_v_superset, __pyx_v_atol); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_8easyCore_5Utils_12coord_cython_4coord_list_mapping_pbc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_subset, PyObject *__pyx_v_superset, PyObject *__pyx_v_atol) { - PyObject *__pyx_v_inds = NULL; - __Pyx_memviewslice __pyx_v_fc1 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_fc2 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_t = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_v_c_inds = { 0, 0, { 0 }, { 0 }, { 0 } }; - __pyx_t_5numpy_float_t __pyx_v_d; - int __pyx_v_ok_inner; - int __pyx_v_ok_outer; - Py_ssize_t __pyx_v_I; - Py_ssize_t __pyx_v_J; - Py_ssize_t __pyx_v_i; - Py_ssize_t __pyx_v_j; - long __pyx_v_k; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - Py_ssize_t __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - __Pyx_memviewslice __pyx_t_7 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } }; - Py_ssize_t __pyx_t_10; - Py_ssize_t __pyx_t_11; - Py_ssize_t __pyx_t_12; - Py_ssize_t __pyx_t_13; - Py_ssize_t __pyx_t_14; - long __pyx_t_15; - Py_ssize_t __pyx_t_16; - Py_ssize_t __pyx_t_17; - Py_ssize_t __pyx_t_18; - Py_ssize_t __pyx_t_19; - int __pyx_t_20; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("coord_list_mapping_pbc", 0); - __Pyx_INCREF(__pyx_v_subset); - __Pyx_INCREF(__pyx_v_superset); - - /* "easyCore/Utils/coord_cython.pyx":237 - * list of indices such that superset[indices] = subset - * """ - * inds = np.zeros(len(subset), dtype=np.int) - 1 # <<<<<<<<<<<<<< - * subset = np.atleast_2d(subset) - * superset = np.atleast_2d(superset) - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_3 = PyObject_Length(__pyx_v_subset); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(0, 237, __pyx_L1_error) - __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_int_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_6) < 0) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_SubtractObjC(__pyx_t_6, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_v_inds = __pyx_t_1; - __pyx_t_1 = 0; - - /* "easyCore/Utils/coord_cython.pyx":238 - * """ - * inds = np.zeros(len(subset), dtype=np.int) - 1 - * subset = np.atleast_2d(subset) # <<<<<<<<<<<<<< - * superset = np.atleast_2d(superset) - * - */ - __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_np); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 238, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_atleast_2d); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 238, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_6 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_6)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_6); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - } - } - __pyx_t_1 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_v_subset) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_subset); - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 238, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF_SET(__pyx_v_subset, __pyx_t_1); - __pyx_t_1 = 0; - - /* "easyCore/Utils/coord_cython.pyx":239 - * inds = np.zeros(len(subset), dtype=np.int) - 1 - * subset = np.atleast_2d(subset) - * superset = np.atleast_2d(superset) # <<<<<<<<<<<<<< - * - * cdef np.float_t[:, :] fc1 = subset - */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 239, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_atleast_2d); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 239, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_6); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_6, function); - } - } - __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_4, __pyx_v_superset) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_superset); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 239, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF_SET(__pyx_v_superset, __pyx_t_1); - __pyx_t_1 = 0; - - /* "easyCore/Utils/coord_cython.pyx":241 - * superset = np.atleast_2d(superset) - * - * cdef np.float_t[:, :] fc1 = subset # <<<<<<<<<<<<<< - * cdef np.float_t[:, :] fc2 = superset - * cdef np.float_t[:] t = atol - */ - __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_float_t(__pyx_v_subset, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 241, __pyx_L1_error) - __pyx_v_fc1 = __pyx_t_7; - __pyx_t_7.memview = NULL; - __pyx_t_7.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":242 - * - * cdef np.float_t[:, :] fc1 = subset - * cdef np.float_t[:, :] fc2 = superset # <<<<<<<<<<<<<< - * cdef np.float_t[:] t = atol - * cdef np.int_t[:] c_inds = inds - */ - __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_float_t(__pyx_v_superset, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 242, __pyx_L1_error) - __pyx_v_fc2 = __pyx_t_7; - __pyx_t_7.memview = NULL; - __pyx_t_7.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":243 - * cdef np.float_t[:, :] fc1 = subset - * cdef np.float_t[:, :] fc2 = superset - * cdef np.float_t[:] t = atol # <<<<<<<<<<<<<< - * cdef np.int_t[:] c_inds = inds - * cdef np.float_t d - */ - __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float_t(__pyx_v_atol, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 243, __pyx_L1_error) - __pyx_v_t = __pyx_t_8; - __pyx_t_8.memview = NULL; - __pyx_t_8.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":244 - * cdef np.float_t[:, :] fc2 = superset - * cdef np.float_t[:] t = atol - * cdef np.int_t[:] c_inds = inds # <<<<<<<<<<<<<< - * cdef np.float_t d - * cdef bint ok_inner, ok_outer - */ - __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int_t(__pyx_v_inds, PyBUF_WRITABLE); if (unlikely(!__pyx_t_9.memview)) __PYX_ERR(0, 244, __pyx_L1_error) - __pyx_v_c_inds = __pyx_t_9; - __pyx_t_9.memview = NULL; - __pyx_t_9.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":248 - * cdef bint ok_inner, ok_outer - * - * I = fc1.shape[0] # <<<<<<<<<<<<<< - * J = fc2.shape[0] - * - */ - __pyx_v_I = (__pyx_v_fc1.shape[0]); - - /* "easyCore/Utils/coord_cython.pyx":249 - * - * I = fc1.shape[0] - * J = fc2.shape[0] # <<<<<<<<<<<<<< - * - * for i in range(I): - */ - __pyx_v_J = (__pyx_v_fc2.shape[0]); - - /* "easyCore/Utils/coord_cython.pyx":251 - * J = fc2.shape[0] - * - * for i in range(I): # <<<<<<<<<<<<<< - * ok_outer = False - * for j in range(J): - */ - __pyx_t_3 = __pyx_v_I; - __pyx_t_10 = __pyx_t_3; - for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) { - __pyx_v_i = __pyx_t_11; - - /* "easyCore/Utils/coord_cython.pyx":252 - * - * for i in range(I): - * ok_outer = False # <<<<<<<<<<<<<< - * for j in range(J): - * ok_inner = True - */ - __pyx_v_ok_outer = 0; - - /* "easyCore/Utils/coord_cython.pyx":253 - * for i in range(I): - * ok_outer = False - * for j in range(J): # <<<<<<<<<<<<<< - * ok_inner = True - * for k in range(3): - */ - __pyx_t_12 = __pyx_v_J; - __pyx_t_13 = __pyx_t_12; - for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) { - __pyx_v_j = __pyx_t_14; - - /* "easyCore/Utils/coord_cython.pyx":254 - * ok_outer = False - * for j in range(J): - * ok_inner = True # <<<<<<<<<<<<<< - * for k in range(3): - * d = fc1[i, k] - fc2[j, k] - */ - __pyx_v_ok_inner = 1; - - /* "easyCore/Utils/coord_cython.pyx":255 - * for j in range(J): - * ok_inner = True - * for k in range(3): # <<<<<<<<<<<<<< - * d = fc1[i, k] - fc2[j, k] - * if fabs(d - round(d)) > t[k]: - */ - for (__pyx_t_15 = 0; __pyx_t_15 < 3; __pyx_t_15+=1) { - __pyx_v_k = __pyx_t_15; - - /* "easyCore/Utils/coord_cython.pyx":256 - * ok_inner = True - * for k in range(3): - * d = fc1[i, k] - fc2[j, k] # <<<<<<<<<<<<<< - * if fabs(d - round(d)) > t[k]: - * ok_inner = False - */ - __pyx_t_16 = __pyx_v_i; - __pyx_t_17 = __pyx_v_k; - __pyx_t_18 = __pyx_v_j; - __pyx_t_19 = __pyx_v_k; - __pyx_v_d = ((*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fc1.data + __pyx_t_16 * __pyx_v_fc1.strides[0]) ) + __pyx_t_17 * __pyx_v_fc1.strides[1]) ))) - (*((__pyx_t_5numpy_float_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_fc2.data + __pyx_t_18 * __pyx_v_fc2.strides[0]) ) + __pyx_t_19 * __pyx_v_fc2.strides[1]) )))); - - /* "easyCore/Utils/coord_cython.pyx":257 - * for k in range(3): - * d = fc1[i, k] - fc2[j, k] - * if fabs(d - round(d)) > t[k]: # <<<<<<<<<<<<<< - * ok_inner = False - * break - */ - __pyx_t_19 = __pyx_v_k; - __pyx_t_20 = ((fabs((__pyx_v_d - round(__pyx_v_d))) > (*((__pyx_t_5numpy_float_t *) ( /* dim=0 */ (__pyx_v_t.data + __pyx_t_19 * __pyx_v_t.strides[0]) )))) != 0); - if (__pyx_t_20) { - - /* "easyCore/Utils/coord_cython.pyx":258 - * d = fc1[i, k] - fc2[j, k] - * if fabs(d - round(d)) > t[k]: - * ok_inner = False # <<<<<<<<<<<<<< - * break - * if ok_inner: - */ - __pyx_v_ok_inner = 0; - - /* "easyCore/Utils/coord_cython.pyx":259 - * if fabs(d - round(d)) > t[k]: - * ok_inner = False - * break # <<<<<<<<<<<<<< - * if ok_inner: - * if c_inds[i] >= 0: - */ - goto __pyx_L8_break; - - /* "easyCore/Utils/coord_cython.pyx":257 - * for k in range(3): - * d = fc1[i, k] - fc2[j, k] - * if fabs(d - round(d)) > t[k]: # <<<<<<<<<<<<<< - * ok_inner = False - * break - */ - } - } - __pyx_L8_break:; - - /* "easyCore/Utils/coord_cython.pyx":260 - * ok_inner = False - * break - * if ok_inner: # <<<<<<<<<<<<<< - * if c_inds[i] >= 0: - * raise ValueError("Something wrong with the inputs, likely duplicates " - */ - __pyx_t_20 = (__pyx_v_ok_inner != 0); - if (__pyx_t_20) { - - /* "easyCore/Utils/coord_cython.pyx":261 - * break - * if ok_inner: - * if c_inds[i] >= 0: # <<<<<<<<<<<<<< - * raise ValueError("Something wrong with the inputs, likely duplicates " - * "in superset") - */ - __pyx_t_19 = __pyx_v_i; - __pyx_t_20 = (((*((__pyx_t_5numpy_int_t *) ( /* dim=0 */ (__pyx_v_c_inds.data + __pyx_t_19 * __pyx_v_c_inds.strides[0]) ))) >= 0) != 0); - if (unlikely(__pyx_t_20)) { - - /* "easyCore/Utils/coord_cython.pyx":262 - * if ok_inner: - * if c_inds[i] >= 0: - * raise ValueError("Something wrong with the inputs, likely duplicates " # <<<<<<<<<<<<<< - * "in superset") - * c_inds[i] = j - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 262, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 262, __pyx_L1_error) - - /* "easyCore/Utils/coord_cython.pyx":261 - * break - * if ok_inner: - * if c_inds[i] >= 0: # <<<<<<<<<<<<<< - * raise ValueError("Something wrong with the inputs, likely duplicates " - * "in superset") - */ - } - - /* "easyCore/Utils/coord_cython.pyx":264 - * raise ValueError("Something wrong with the inputs, likely duplicates " - * "in superset") - * c_inds[i] = j # <<<<<<<<<<<<<< - * ok_outer = True - * # we don't break here so we can check for duplicates in superset - */ - __pyx_t_19 = __pyx_v_i; - *((__pyx_t_5numpy_int_t *) ( /* dim=0 */ (__pyx_v_c_inds.data + __pyx_t_19 * __pyx_v_c_inds.strides[0]) )) = __pyx_v_j; - - /* "easyCore/Utils/coord_cython.pyx":265 - * "in superset") - * c_inds[i] = j - * ok_outer = True # <<<<<<<<<<<<<< - * # we don't break here so we can check for duplicates in superset - * if not ok_outer: - */ - __pyx_v_ok_outer = 1; - - /* "easyCore/Utils/coord_cython.pyx":260 - * ok_inner = False - * break - * if ok_inner: # <<<<<<<<<<<<<< - * if c_inds[i] >= 0: - * raise ValueError("Something wrong with the inputs, likely duplicates " - */ - } - } - - /* "easyCore/Utils/coord_cython.pyx":267 - * ok_outer = True - * # we don't break here so we can check for duplicates in superset - * if not ok_outer: # <<<<<<<<<<<<<< - * break - * - */ - __pyx_t_20 = ((!(__pyx_v_ok_outer != 0)) != 0); - if (__pyx_t_20) { - - /* "easyCore/Utils/coord_cython.pyx":268 - * # we don't break here so we can check for duplicates in superset - * if not ok_outer: - * break # <<<<<<<<<<<<<< - * - * if not ok_outer: - */ - goto __pyx_L4_break; - - /* "easyCore/Utils/coord_cython.pyx":267 - * ok_outer = True - * # we don't break here so we can check for duplicates in superset - * if not ok_outer: # <<<<<<<<<<<<<< - * break - * - */ - } - } - __pyx_L4_break:; - - /* "easyCore/Utils/coord_cython.pyx":270 - * break - * - * if not ok_outer: # <<<<<<<<<<<<<< - * raise ValueError("subset is not a subset of superset") - * - */ - __pyx_t_20 = ((!(__pyx_v_ok_outer != 0)) != 0); - if (unlikely(__pyx_t_20)) { - - /* "easyCore/Utils/coord_cython.pyx":271 - * - * if not ok_outer: - * raise ValueError("subset is not a subset of superset") # <<<<<<<<<<<<<< - * - * return inds - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 271, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 271, __pyx_L1_error) - - /* "easyCore/Utils/coord_cython.pyx":270 - * break - * - * if not ok_outer: # <<<<<<<<<<<<<< - * raise ValueError("subset is not a subset of superset") - * - */ - } - - /* "easyCore/Utils/coord_cython.pyx":273 - * raise ValueError("subset is not a subset of superset") - * - * return inds # <<<<<<<<<<<<<< - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_inds); - __pyx_r = __pyx_v_inds; - goto __pyx_L0; - - /* "easyCore/Utils/coord_cython.pyx":226 - * @cython.wraparound(False) - * @cython.initializedcheck(False) - * def coord_list_mapping_pbc(subset, superset, atol=1e-8): # <<<<<<<<<<<<<< - * """ - * Gives the index mapping from a subset to a superset. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1); - __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1); - __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1); - __Pyx_AddTraceback("easyCore.Utils.coord_cython.coord_list_mapping_pbc", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_inds); - __PYX_XDEC_MEMVIEW(&__pyx_v_fc1, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_fc2, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_t, 1); - __PYX_XDEC_MEMVIEW(&__pyx_v_c_inds, 1); - __Pyx_XDECREF(__pyx_v_subset); - __Pyx_XDECREF(__pyx_v_superset); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":742 - * ctypedef npy_cdouble complex_t - * - * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(1, a) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":743 - * - * cdef inline object PyArray_MultiIterNew1(a): - * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew2(a, b): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 743, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":742 - * ctypedef npy_cdouble complex_t - * - * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(1, a) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":745 - * return PyArray_MultiIterNew(1, a) - * - * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(2, a, b) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":746 - * - * cdef inline object PyArray_MultiIterNew2(a, b): - * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 746, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":745 - * return PyArray_MultiIterNew(1, a) - * - * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(2, a, b) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":748 - * return PyArray_MultiIterNew(2, a, b) - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(3, a, b, c) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":749 - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): - * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 749, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":748 - * return PyArray_MultiIterNew(2, a, b) - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(3, a, b, c) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":751 - * return PyArray_MultiIterNew(3, a, b, c) - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(4, a, b, c, d) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":752 - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): - * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 752, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":751 - * return PyArray_MultiIterNew(3, a, b, c) - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(4, a, b, c, d) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":754 - * return PyArray_MultiIterNew(4, a, b, c, d) - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":755 - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): - * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< - * - * cdef inline tuple PyDataType_SHAPE(dtype d): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 755, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":754 - * return PyArray_MultiIterNew(4, a, b, c, d) - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":757 - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__pyx_v_d) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("PyDataType_SHAPE", 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":758 - * - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< - * return d.subarray.shape - * else: - */ - __pyx_t_1 = (PyDataType_HASSUBARRAY(__pyx_v_d) != 0); - if (__pyx_t_1) { - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":759 - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape # <<<<<<<<<<<<<< - * else: - * return () - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject*)__pyx_v_d->subarray->shape)); - __pyx_r = ((PyObject*)__pyx_v_d->subarray->shape); - goto __pyx_L0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":758 - * - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< - * return d.subarray.shape - * else: - */ - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":761 - * return d.subarray.shape - * else: - * return () # <<<<<<<<<<<<<< - * - * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_empty_tuple); - __pyx_r = __pyx_empty_tuple; - goto __pyx_L0; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":757 - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":763 - * return () - * - * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< - * # Recursive utility function used in __getbuffer__ to get format - * # string. The new location in the format string is returned. - */ - -static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) { - PyArray_Descr *__pyx_v_child = 0; - int __pyx_v_endian_detector; - int __pyx_v_little_endian; - PyObject *__pyx_v_fields = 0; - PyObject *__pyx_v_childname = NULL; - PyObject *__pyx_v_new_offset = NULL; - PyObject *__pyx_v_t = NULL; - char *__pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - int __pyx_t_6; - int __pyx_t_7; - long __pyx_t_8; - char *__pyx_t_9; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_util_dtypestring", 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":768 - * - * cdef dtype child - * cdef int endian_detector = 1 # <<<<<<<<<<<<<< - * cdef bint little_endian = ((&endian_detector)[0] != 0) - * cdef tuple fields - */ - __pyx_v_endian_detector = 1; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":769 - * cdef dtype child - * cdef int endian_detector = 1 - * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< - * cdef tuple fields - * - */ - __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":772 - * cdef tuple fields - * - * for childname in descr.names: # <<<<<<<<<<<<<< - * fields = descr.fields[childname] - * child, new_offset = fields - */ - if (unlikely(__pyx_v_descr->names == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); - __PYX_ERR(1, 772, __pyx_L1_error) - } - __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; - for (;;) { - if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(1, 772, __pyx_L1_error) - #else - __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 772, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - #endif - __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3); - __pyx_t_3 = 0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":773 - * - * for childname in descr.names: - * fields = descr.fields[childname] # <<<<<<<<<<<<<< - * child, new_offset = fields - * - */ - if (unlikely(__pyx_v_descr->fields == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 773, __pyx_L1_error) - } - __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 773, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) __PYX_ERR(1, 773, __pyx_L1_error) - __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3)); - __pyx_t_3 = 0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":774 - * for childname in descr.names: - * fields = descr.fields[childname] - * child, new_offset = fields # <<<<<<<<<<<<<< - * - * if (end - f) - (new_offset - offset[0]) < 15: - */ - if (likely(__pyx_v_fields != Py_None)) { - PyObject* sequence = __pyx_v_fields; - Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); - if (unlikely(size != 2)) { - if (size > 2) __Pyx_RaiseTooManyValuesError(2); - else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(1, 774, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - #else - __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 774, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 774, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - #endif - } else { - __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(1, 774, __pyx_L1_error) - } - if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) __PYX_ERR(1, 774, __pyx_L1_error) - __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3)); - __pyx_t_3 = 0; - __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4); - __pyx_t_4 = 0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":776 - * child, new_offset = fields - * - * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - */ - __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 776, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 776, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 776, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0); - if (unlikely(__pyx_t_6)) { - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":777 - * - * if (end - f) - (new_offset - offset[0]) < 15: - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< - * - * if ((child.byteorder == c'>' and little_endian) or - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 777, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 777, __pyx_L1_error) - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":776 - * child, new_offset = fields - * - * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - */ - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":779 - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0); - if (!__pyx_t_7) { - goto __pyx_L8_next_or; - } else { - } - __pyx_t_7 = (__pyx_v_little_endian != 0); - if (!__pyx_t_7) { - } else { - __pyx_t_6 = __pyx_t_7; - goto __pyx_L7_bool_binop_done; - } - __pyx_L8_next_or:; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":780 - * - * if ((child.byteorder == c'>' and little_endian) or - * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< - * raise ValueError(u"Non-native byte order not supported") - * # One could encode it in the format string and have Cython - */ - __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0); - if (__pyx_t_7) { - } else { - __pyx_t_6 = __pyx_t_7; - goto __pyx_L7_bool_binop_done; - } - __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0); - __pyx_t_6 = __pyx_t_7; - __pyx_L7_bool_binop_done:; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":779 - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - if (unlikely(__pyx_t_6)) { - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":781 - * if ((child.byteorder == c'>' and little_endian) or - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< - * # One could encode it in the format string and have Cython - * # complain instead, BUT: < and > in format strings also imply - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 781, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 781, __pyx_L1_error) - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":779 - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":791 - * - * # Output padding bytes - * while offset[0] < new_offset: # <<<<<<<<<<<<<< - * f[0] = 120 # "x"; pad byte - * f += 1 - */ - while (1) { - __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 791, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 791, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 791, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (!__pyx_t_6) break; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":792 - * # Output padding bytes - * while offset[0] < new_offset: - * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<< - * f += 1 - * offset[0] += 1 - */ - (__pyx_v_f[0]) = 0x78; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":793 - * while offset[0] < new_offset: - * f[0] = 120 # "x"; pad byte - * f += 1 # <<<<<<<<<<<<<< - * offset[0] += 1 - * - */ - __pyx_v_f = (__pyx_v_f + 1); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":794 - * f[0] = 120 # "x"; pad byte - * f += 1 - * offset[0] += 1 # <<<<<<<<<<<<<< - * - * offset[0] += child.itemsize - */ - __pyx_t_8 = 0; - (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1); - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":796 - * offset[0] += 1 - * - * offset[0] += child.itemsize # <<<<<<<<<<<<<< - * - * if not PyDataType_HASFIELDS(child): - */ - __pyx_t_8 = 0; - (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":798 - * offset[0] += child.itemsize - * - * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< - * t = child.type_num - * if end - f < 5: - */ - __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0); - if (__pyx_t_6) { - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":799 - * - * if not PyDataType_HASFIELDS(child): - * t = child.type_num # <<<<<<<<<<<<<< - * if end - f < 5: - * raise RuntimeError(u"Format string allocated too short.") - */ - __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 799, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4); - __pyx_t_4 = 0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":800 - * if not PyDataType_HASFIELDS(child): - * t = child.type_num - * if end - f < 5: # <<<<<<<<<<<<<< - * raise RuntimeError(u"Format string allocated too short.") - * - */ - __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0); - if (unlikely(__pyx_t_6)) { - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":801 - * t = child.type_num - * if end - f < 5: - * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< - * - * # Until ticket #99 is fixed, use integers to avoid warnings - */ - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 801, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_Raise(__pyx_t_4, 0, 0, 0); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __PYX_ERR(1, 801, __pyx_L1_error) - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":800 - * if not PyDataType_HASFIELDS(child): - * t = child.type_num - * if end - f < 5: # <<<<<<<<<<<<<< - * raise RuntimeError(u"Format string allocated too short.") - * - */ - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":804 - * - * # Until ticket #99 is fixed, use integers to avoid warnings - * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<< - * elif t == NPY_UBYTE: f[0] = 66 #"B" - * elif t == NPY_SHORT: f[0] = 104 #"h" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_BYTE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 804, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 804, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 804, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 98; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":805 - * # Until ticket #99 is fixed, use integers to avoid warnings - * if t == NPY_BYTE: f[0] = 98 #"b" - * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<< - * elif t == NPY_SHORT: f[0] = 104 #"h" - * elif t == NPY_USHORT: f[0] = 72 #"H" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UBYTE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 805, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 805, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 805, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 66; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":806 - * if t == NPY_BYTE: f[0] = 98 #"b" - * elif t == NPY_UBYTE: f[0] = 66 #"B" - * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<< - * elif t == NPY_USHORT: f[0] = 72 #"H" - * elif t == NPY_INT: f[0] = 105 #"i" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_SHORT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 806, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 806, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 806, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x68; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":807 - * elif t == NPY_UBYTE: f[0] = 66 #"B" - * elif t == NPY_SHORT: f[0] = 104 #"h" - * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<< - * elif t == NPY_INT: f[0] = 105 #"i" - * elif t == NPY_UINT: f[0] = 73 #"I" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_USHORT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 807, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 807, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 807, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 72; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":808 - * elif t == NPY_SHORT: f[0] = 104 #"h" - * elif t == NPY_USHORT: f[0] = 72 #"H" - * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<< - * elif t == NPY_UINT: f[0] = 73 #"I" - * elif t == NPY_LONG: f[0] = 108 #"l" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_INT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 808, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 808, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 808, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x69; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":809 - * elif t == NPY_USHORT: f[0] = 72 #"H" - * elif t == NPY_INT: f[0] = 105 #"i" - * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<< - * elif t == NPY_LONG: f[0] = 108 #"l" - * elif t == NPY_ULONG: f[0] = 76 #"L" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UINT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 809, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 809, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 809, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 73; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":810 - * elif t == NPY_INT: f[0] = 105 #"i" - * elif t == NPY_UINT: f[0] = 73 #"I" - * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<< - * elif t == NPY_ULONG: f[0] = 76 #"L" - * elif t == NPY_LONGLONG: f[0] = 113 #"q" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 810, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 810, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 810, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x6C; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":811 - * elif t == NPY_UINT: f[0] = 73 #"I" - * elif t == NPY_LONG: f[0] = 108 #"l" - * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<< - * elif t == NPY_LONGLONG: f[0] = 113 #"q" - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 811, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 811, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 811, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 76; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":812 - * elif t == NPY_LONG: f[0] = 108 #"l" - * elif t == NPY_ULONG: f[0] = 76 #"L" - * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<< - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - * elif t == NPY_FLOAT: f[0] = 102 #"f" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 812, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 812, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 812, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x71; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":813 - * elif t == NPY_ULONG: f[0] = 76 #"L" - * elif t == NPY_LONGLONG: f[0] = 113 #"q" - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<< - * elif t == NPY_FLOAT: f[0] = 102 #"f" - * elif t == NPY_DOUBLE: f[0] = 100 #"d" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 813, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 813, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 813, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 81; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":814 - * elif t == NPY_LONGLONG: f[0] = 113 #"q" - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<< - * elif t == NPY_DOUBLE: f[0] = 100 #"d" - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_FLOAT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 814, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 814, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 814, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x66; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":815 - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - * elif t == NPY_FLOAT: f[0] = 102 #"f" - * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<< - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 815, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 815, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 815, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x64; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":816 - * elif t == NPY_FLOAT: f[0] = 102 #"f" - * elif t == NPY_DOUBLE: f[0] = 100 #"d" - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<< - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 816, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 816, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 816, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x67; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":817 - * elif t == NPY_DOUBLE: f[0] = 100 #"d" - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<< - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd - * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 817, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 817, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 817, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 90; - (__pyx_v_f[1]) = 0x66; - __pyx_v_f = (__pyx_v_f + 1); - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":818 - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<< - * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg - * elif t == NPY_OBJECT: f[0] = 79 #"O" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 818, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 818, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 818, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 90; - (__pyx_v_f[1]) = 0x64; - __pyx_v_f = (__pyx_v_f + 1); - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":819 - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd - * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<< - * elif t == NPY_OBJECT: f[0] = 79 #"O" - * else: - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 819, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 819, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 819, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 90; - (__pyx_v_f[1]) = 0x67; - __pyx_v_f = (__pyx_v_f + 1); - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":820 - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd - * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg - * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<< - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_OBJECT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 820, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 820, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 820, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (likely(__pyx_t_6)) { - (__pyx_v_f[0]) = 79; - goto __pyx_L15; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":822 - * elif t == NPY_OBJECT: f[0] = 79 #"O" - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< - * f += 1 - * else: - */ - /*else*/ { - __pyx_t_3 = __Pyx_PyUnicode_FormatSafe(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 822, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 822, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_4, 0, 0, 0); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __PYX_ERR(1, 822, __pyx_L1_error) - } - __pyx_L15:; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":823 - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) - * f += 1 # <<<<<<<<<<<<<< - * else: - * # Cython ignores struct boundary information ("T{...}"), - */ - __pyx_v_f = (__pyx_v_f + 1); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":798 - * offset[0] += child.itemsize - * - * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< - * t = child.type_num - * if end - f < 5: - */ - goto __pyx_L13; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":827 - * # Cython ignores struct boundary information ("T{...}"), - * # so don't output it - * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<< - * return f - * - */ - /*else*/ { - __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == ((char *)NULL))) __PYX_ERR(1, 827, __pyx_L1_error) - __pyx_v_f = __pyx_t_9; - } - __pyx_L13:; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":772 - * cdef tuple fields - * - * for childname in descr.names: # <<<<<<<<<<<<<< - * fields = descr.fields[childname] - * child, new_offset = fields - */ - } - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":828 - * # so don't output it - * f = _util_dtypestring(child, f, end, offset) - * return f # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_f; - goto __pyx_L0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":763 - * return () - * - * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< - * # Recursive utility function used in __getbuffer__ to get format - * # string. The new location in the format string is returned. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_child); - __Pyx_XDECREF(__pyx_v_fields); - __Pyx_XDECREF(__pyx_v_childname); - __Pyx_XDECREF(__pyx_v_new_offset); - __Pyx_XDECREF(__pyx_v_t); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":943 - * int _import_umath() except -1 - * - * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< - * Py_INCREF(base) # important to do this before stealing the reference below! - * PyArray_SetBaseObject(arr, base) - */ - -static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("set_array_base", 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":944 - * - * cdef inline void set_array_base(ndarray arr, object base): - * Py_INCREF(base) # important to do this before stealing the reference below! # <<<<<<<<<<<<<< - * PyArray_SetBaseObject(arr, base) - * - */ - Py_INCREF(__pyx_v_base); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":945 - * cdef inline void set_array_base(ndarray arr, object base): - * Py_INCREF(base) # important to do this before stealing the reference below! - * PyArray_SetBaseObject(arr, base) # <<<<<<<<<<<<<< - * - * cdef inline object get_array_base(ndarray arr): - */ - (void)(PyArray_SetBaseObject(__pyx_v_arr, __pyx_v_base)); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":943 - * int _import_umath() except -1 - * - * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< - * Py_INCREF(base) # important to do this before stealing the reference below! - * PyArray_SetBaseObject(arr, base) - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":947 - * PyArray_SetBaseObject(arr, base) - * - * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< - * base = PyArray_BASE(arr) - * if base is NULL: - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) { - PyObject *__pyx_v_base; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("get_array_base", 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":948 - * - * cdef inline object get_array_base(ndarray arr): - * base = PyArray_BASE(arr) # <<<<<<<<<<<<<< - * if base is NULL: - * return None - */ - __pyx_v_base = PyArray_BASE(__pyx_v_arr); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":949 - * cdef inline object get_array_base(ndarray arr): - * base = PyArray_BASE(arr) - * if base is NULL: # <<<<<<<<<<<<<< - * return None - * return base - */ - __pyx_t_1 = ((__pyx_v_base == NULL) != 0); - if (__pyx_t_1) { - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":950 - * base = PyArray_BASE(arr) - * if base is NULL: - * return None # <<<<<<<<<<<<<< - * return base - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":949 - * cdef inline object get_array_base(ndarray arr): - * base = PyArray_BASE(arr) - * if base is NULL: # <<<<<<<<<<<<<< - * return None - * return base - */ - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":951 - * if base is NULL: - * return None - * return base # <<<<<<<<<<<<<< - * - * # Versions of the import_* functions which are more suitable for - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_base)); - __pyx_r = ((PyObject *)__pyx_v_base); - goto __pyx_L0; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":947 - * PyArray_SetBaseObject(arr, base) - * - * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< - * base = PyArray_BASE(arr) - * if base is NULL: - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":955 - * # Versions of the import_* functions which are more suitable for - * # Cython code. - * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< - * try: - * __pyx_import_array() - */ - -static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("import_array", 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":956 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * __pyx_import_array() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":957 - * cdef inline int import_array() except -1: - * try: - * __pyx_import_array() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") - */ - __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 957, __pyx_L3_error) - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":956 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * __pyx_import_array() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":958 - * try: - * __pyx_import_array() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.multiarray failed to import") - * - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 958, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":959 - * __pyx_import_array() - * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_umath() except -1: - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 959, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(1, 959, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":956 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * __pyx_import_array() - * except Exception: - */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":955 - * # Versions of the import_* functions which are more suitable for - * # Cython code. - * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< - * try: - * __pyx_import_array() - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":961 - * raise ImportError("numpy.core.multiarray failed to import") - * - * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - -static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("import_umath", 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":962 - * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":963 - * cdef inline int import_umath() except -1: - * try: - * _import_umath() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy.core.umath failed to import") - */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 963, __pyx_L3_error) - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":962 - * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":964 - * try: - * _import_umath() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.umath failed to import") - * - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 964, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":965 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_ufunc() except -1: - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 965, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(1, 965, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":962 - * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":961 - * raise ImportError("numpy.core.multiarray failed to import") - * - * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":967 - * raise ImportError("numpy.core.umath failed to import") - * - * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - -static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("import_ufunc", 0); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":968 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":969 - * cdef inline int import_ufunc() except -1: - * try: - * _import_umath() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy.core.umath failed to import") - */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 969, __pyx_L3_error) - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":968 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":970 - * try: - * _import_umath() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.umath failed to import") - * - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 970, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":971 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< - * - * cdef extern from *: - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 971, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(1, 971, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":968 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":967 - * raise ImportError("numpy.core.umath failed to import") - * - * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":122 - * cdef bint dtype_is_object - * - * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< - * mode="c", bint allocate_buffer=True): - * - */ - -/* Python wrapper */ -static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_shape = 0; - Py_ssize_t __pyx_v_itemsize; - PyObject *__pyx_v_format = 0; - PyObject *__pyx_v_mode = 0; - int __pyx_v_allocate_buffer; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0}; - PyObject* values[5] = {0,0,0,0,0}; - values[3] = ((PyObject *)__pyx_n_s_c); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); __PYX_ERR(2, 122, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); __PYX_ERR(2, 122, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mode); - if (value) { values[3] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 4: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_allocate_buffer); - if (value) { values[4] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(2, 122, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_shape = ((PyObject*)values[0]); - __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 122, __pyx_L3_error) - __pyx_v_format = values[2]; - __pyx_v_mode = values[3]; - if (values[4]) { - __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 123, __pyx_L3_error) - } else { - - /* "View.MemoryView":123 - * - * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, - * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<< - * - * cdef int idx - */ - __pyx_v_allocate_buffer = ((int)1); - } - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(2, 122, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) __PYX_ERR(2, 122, __pyx_L1_error) - if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) { - PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); __PYX_ERR(2, 122, __pyx_L1_error) - } - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer); - - /* "View.MemoryView":122 - * cdef bint dtype_is_object - * - * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< - * mode="c", bint allocate_buffer=True): - * - */ - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) { - int __pyx_v_idx; - Py_ssize_t __pyx_v_i; - Py_ssize_t __pyx_v_dim; - PyObject **__pyx_v_p; - char __pyx_v_order; - int __pyx_r; - __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - char *__pyx_t_7; - int __pyx_t_8; - Py_ssize_t __pyx_t_9; - PyObject *__pyx_t_10 = NULL; - Py_ssize_t __pyx_t_11; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__cinit__", 0); - __Pyx_INCREF(__pyx_v_format); - - /* "View.MemoryView":129 - * cdef PyObject **p - * - * self.ndim = len(shape) # <<<<<<<<<<<<<< - * self.itemsize = itemsize - * - */ - if (unlikely(__pyx_v_shape == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(2, 129, __pyx_L1_error) - } - __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(2, 129, __pyx_L1_error) - __pyx_v_self->ndim = ((int)__pyx_t_1); - - /* "View.MemoryView":130 - * - * self.ndim = len(shape) - * self.itemsize = itemsize # <<<<<<<<<<<<<< - * - * if not self.ndim: - */ - __pyx_v_self->itemsize = __pyx_v_itemsize; - - /* "View.MemoryView":132 - * self.itemsize = itemsize - * - * if not self.ndim: # <<<<<<<<<<<<<< - * raise ValueError("Empty shape tuple for cython.array") - * - */ - __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0); - if (unlikely(__pyx_t_2)) { - - /* "View.MemoryView":133 - * - * if not self.ndim: - * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<< - * - * if itemsize <= 0: - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 133, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 133, __pyx_L1_error) - - /* "View.MemoryView":132 - * self.itemsize = itemsize - * - * if not self.ndim: # <<<<<<<<<<<<<< - * raise ValueError("Empty shape tuple for cython.array") - * - */ - } - - /* "View.MemoryView":135 - * raise ValueError("Empty shape tuple for cython.array") - * - * if itemsize <= 0: # <<<<<<<<<<<<<< - * raise ValueError("itemsize <= 0 for cython.array") - * - */ - __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0); - if (unlikely(__pyx_t_2)) { - - /* "View.MemoryView":136 - * - * if itemsize <= 0: - * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<< - * - * if not isinstance(format, bytes): - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 136, __pyx_L1_error) - - /* "View.MemoryView":135 - * raise ValueError("Empty shape tuple for cython.array") - * - * if itemsize <= 0: # <<<<<<<<<<<<<< - * raise ValueError("itemsize <= 0 for cython.array") - * - */ - } - - /* "View.MemoryView":138 - * raise ValueError("itemsize <= 0 for cython.array") - * - * if not isinstance(format, bytes): # <<<<<<<<<<<<<< - * format = format.encode('ASCII') - * self._format = format # keep a reference to the byte string - */ - __pyx_t_2 = PyBytes_Check(__pyx_v_format); - __pyx_t_4 = ((!(__pyx_t_2 != 0)) != 0); - if (__pyx_t_4) { - - /* "View.MemoryView":139 - * - * if not isinstance(format, bytes): - * format = format.encode('ASCII') # <<<<<<<<<<<<<< - * self._format = format # keep a reference to the byte string - * self.format = self._format - */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_format, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 139, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5); - if (likely(__pyx_t_6)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_6); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_5, function); - } - } - __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_n_s_ASCII) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_n_s_ASCII); - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 139, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":138 - * raise ValueError("itemsize <= 0 for cython.array") - * - * if not isinstance(format, bytes): # <<<<<<<<<<<<<< - * format = format.encode('ASCII') - * self._format = format # keep a reference to the byte string - */ - } - - /* "View.MemoryView":140 - * if not isinstance(format, bytes): - * format = format.encode('ASCII') - * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<< - * self.format = self._format - * - */ - if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) __PYX_ERR(2, 140, __pyx_L1_error) - __pyx_t_3 = __pyx_v_format; - __Pyx_INCREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - __Pyx_GOTREF(__pyx_v_self->_format); - __Pyx_DECREF(__pyx_v_self->_format); - __pyx_v_self->_format = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":141 - * format = format.encode('ASCII') - * self._format = format # keep a reference to the byte string - * self.format = self._format # <<<<<<<<<<<<<< - * - * - */ - if (unlikely(__pyx_v_self->_format == Py_None)) { - PyErr_SetString(PyExc_TypeError, "expected bytes, NoneType found"); - __PYX_ERR(2, 141, __pyx_L1_error) - } - __pyx_t_7 = __Pyx_PyBytes_AsWritableString(__pyx_v_self->_format); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) __PYX_ERR(2, 141, __pyx_L1_error) - __pyx_v_self->format = __pyx_t_7; - - /* "View.MemoryView":144 - * - * - * self._shape = PyObject_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<< - * self._strides = self._shape + self.ndim - * - */ - __pyx_v_self->_shape = ((Py_ssize_t *)PyObject_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2))); - - /* "View.MemoryView":145 - * - * self._shape = PyObject_Malloc(sizeof(Py_ssize_t)*self.ndim*2) - * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<< - * - * if not self._shape: - */ - __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim); - - /* "View.MemoryView":147 - * self._strides = self._shape + self.ndim - * - * if not self._shape: # <<<<<<<<<<<<<< - * raise MemoryError("unable to allocate shape and strides.") - * - */ - __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0); - if (unlikely(__pyx_t_4)) { - - /* "View.MemoryView":148 - * - * if not self._shape: - * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 148, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 148, __pyx_L1_error) - - /* "View.MemoryView":147 - * self._strides = self._shape + self.ndim - * - * if not self._shape: # <<<<<<<<<<<<<< - * raise MemoryError("unable to allocate shape and strides.") - * - */ - } - - /* "View.MemoryView":151 - * - * - * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<< - * if dim <= 0: - * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) - */ - __pyx_t_8 = 0; - __pyx_t_3 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0; - for (;;) { - if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_5); __pyx_t_1++; if (unlikely(0 < 0)) __PYX_ERR(2, 151, __pyx_L1_error) - #else - __pyx_t_5 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 151, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_t_5); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 151, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_v_dim = __pyx_t_9; - __pyx_v_idx = __pyx_t_8; - __pyx_t_8 = (__pyx_t_8 + 1); - - /* "View.MemoryView":152 - * - * for idx, dim in enumerate(shape): - * if dim <= 0: # <<<<<<<<<<<<<< - * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) - * self._shape[idx] = dim - */ - __pyx_t_4 = ((__pyx_v_dim <= 0) != 0); - if (unlikely(__pyx_t_4)) { - - /* "View.MemoryView":153 - * for idx, dim in enumerate(shape): - * if dim <= 0: - * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<< - * self._shape[idx] = dim - * - */ - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 153, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 153, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 153, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_6); - __pyx_t_5 = 0; - __pyx_t_6 = 0; - __pyx_t_6 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 153, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_6); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 153, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_Raise(__pyx_t_10, 0, 0, 0); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __PYX_ERR(2, 153, __pyx_L1_error) - - /* "View.MemoryView":152 - * - * for idx, dim in enumerate(shape): - * if dim <= 0: # <<<<<<<<<<<<<< - * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) - * self._shape[idx] = dim - */ - } - - /* "View.MemoryView":154 - * if dim <= 0: - * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) - * self._shape[idx] = dim # <<<<<<<<<<<<<< - * - * cdef char order - */ - (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim; - - /* "View.MemoryView":151 - * - * - * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<< - * if dim <= 0: - * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) - */ - } - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "View.MemoryView":157 - * - * cdef char order - * if mode == 'fortran': # <<<<<<<<<<<<<< - * order = b'F' - * self.mode = u'fortran' - */ - __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 157, __pyx_L1_error) - if (__pyx_t_4) { - - /* "View.MemoryView":158 - * cdef char order - * if mode == 'fortran': - * order = b'F' # <<<<<<<<<<<<<< - * self.mode = u'fortran' - * elif mode == 'c': - */ - __pyx_v_order = 'F'; - - /* "View.MemoryView":159 - * if mode == 'fortran': - * order = b'F' - * self.mode = u'fortran' # <<<<<<<<<<<<<< - * elif mode == 'c': - * order = b'C' - */ - __Pyx_INCREF(__pyx_n_u_fortran); - __Pyx_GIVEREF(__pyx_n_u_fortran); - __Pyx_GOTREF(__pyx_v_self->mode); - __Pyx_DECREF(__pyx_v_self->mode); - __pyx_v_self->mode = __pyx_n_u_fortran; - - /* "View.MemoryView":157 - * - * cdef char order - * if mode == 'fortran': # <<<<<<<<<<<<<< - * order = b'F' - * self.mode = u'fortran' - */ - goto __pyx_L10; - } - - /* "View.MemoryView":160 - * order = b'F' - * self.mode = u'fortran' - * elif mode == 'c': # <<<<<<<<<<<<<< - * order = b'C' - * self.mode = u'c' - */ - __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 160, __pyx_L1_error) - if (likely(__pyx_t_4)) { - - /* "View.MemoryView":161 - * self.mode = u'fortran' - * elif mode == 'c': - * order = b'C' # <<<<<<<<<<<<<< - * self.mode = u'c' - * else: - */ - __pyx_v_order = 'C'; - - /* "View.MemoryView":162 - * elif mode == 'c': - * order = b'C' - * self.mode = u'c' # <<<<<<<<<<<<<< - * else: - * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) - */ - __Pyx_INCREF(__pyx_n_u_c); - __Pyx_GIVEREF(__pyx_n_u_c); - __Pyx_GOTREF(__pyx_v_self->mode); - __Pyx_DECREF(__pyx_v_self->mode); - __pyx_v_self->mode = __pyx_n_u_c; - - /* "View.MemoryView":160 - * order = b'F' - * self.mode = u'fortran' - * elif mode == 'c': # <<<<<<<<<<<<<< - * order = b'C' - * self.mode = u'c' - */ - goto __pyx_L10; - } - - /* "View.MemoryView":164 - * self.mode = u'c' - * else: - * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<< - * - * self.len = fill_contig_strides_array(self._shape, self._strides, - */ - /*else*/ { - __pyx_t_3 = __Pyx_PyString_FormatSafe(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 164, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_3); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 164, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_10, 0, 0, 0); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __PYX_ERR(2, 164, __pyx_L1_error) - } - __pyx_L10:; - - /* "View.MemoryView":166 - * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) - * - * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<< - * itemsize, self.ndim, order) - * - */ - __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order); - - /* "View.MemoryView":169 - * itemsize, self.ndim, order) - * - * self.free_data = allocate_buffer # <<<<<<<<<<<<<< - * self.dtype_is_object = format == b'O' - * if allocate_buffer: - */ - __pyx_v_self->free_data = __pyx_v_allocate_buffer; - - /* "View.MemoryView":170 - * - * self.free_data = allocate_buffer - * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<< - * if allocate_buffer: - * - */ - __pyx_t_10 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 170, __pyx_L1_error) - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 170, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __pyx_v_self->dtype_is_object = __pyx_t_4; - - /* "View.MemoryView":171 - * self.free_data = allocate_buffer - * self.dtype_is_object = format == b'O' - * if allocate_buffer: # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_4 = (__pyx_v_allocate_buffer != 0); - if (__pyx_t_4) { - - /* "View.MemoryView":174 - * - * - * self.data = malloc(self.len) # <<<<<<<<<<<<<< - * if not self.data: - * raise MemoryError("unable to allocate array data.") - */ - __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len)); - - /* "View.MemoryView":175 - * - * self.data = malloc(self.len) - * if not self.data: # <<<<<<<<<<<<<< - * raise MemoryError("unable to allocate array data.") - * - */ - __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0); - if (unlikely(__pyx_t_4)) { - - /* "View.MemoryView":176 - * self.data = malloc(self.len) - * if not self.data: - * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<< - * - * if self.dtype_is_object: - */ - __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 176, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_Raise(__pyx_t_10, 0, 0, 0); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __PYX_ERR(2, 176, __pyx_L1_error) - - /* "View.MemoryView":175 - * - * self.data = malloc(self.len) - * if not self.data: # <<<<<<<<<<<<<< - * raise MemoryError("unable to allocate array data.") - * - */ - } - - /* "View.MemoryView":178 - * raise MemoryError("unable to allocate array data.") - * - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * p = self.data - * for i in range(self.len / itemsize): - */ - __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0); - if (__pyx_t_4) { - - /* "View.MemoryView":179 - * - * if self.dtype_is_object: - * p = self.data # <<<<<<<<<<<<<< - * for i in range(self.len / itemsize): - * p[i] = Py_None - */ - __pyx_v_p = ((PyObject **)__pyx_v_self->data); - - /* "View.MemoryView":180 - * if self.dtype_is_object: - * p = self.data - * for i in range(self.len / itemsize): # <<<<<<<<<<<<<< - * p[i] = Py_None - * Py_INCREF(Py_None) - */ - if (unlikely(__pyx_v_itemsize == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); - __PYX_ERR(2, 180, __pyx_L1_error) - } - else if (sizeof(Py_ssize_t) == sizeof(long) && (!(((Py_ssize_t)-1) > 0)) && unlikely(__pyx_v_itemsize == (Py_ssize_t)-1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) { - PyErr_SetString(PyExc_OverflowError, "value too large to perform division"); - __PYX_ERR(2, 180, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize); - __pyx_t_9 = __pyx_t_1; - for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_9; __pyx_t_11+=1) { - __pyx_v_i = __pyx_t_11; - - /* "View.MemoryView":181 - * p = self.data - * for i in range(self.len / itemsize): - * p[i] = Py_None # <<<<<<<<<<<<<< - * Py_INCREF(Py_None) - * - */ - (__pyx_v_p[__pyx_v_i]) = Py_None; - - /* "View.MemoryView":182 - * for i in range(self.len / itemsize): - * p[i] = Py_None - * Py_INCREF(Py_None) # <<<<<<<<<<<<<< - * - * @cname('getbuffer') - */ - Py_INCREF(Py_None); - } - - /* "View.MemoryView":178 - * raise MemoryError("unable to allocate array data.") - * - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * p = self.data - * for i in range(self.len / itemsize): - */ - } - - /* "View.MemoryView":171 - * self.free_data = allocate_buffer - * self.dtype_is_object = format == b'O' - * if allocate_buffer: # <<<<<<<<<<<<<< - * - * - */ - } - - /* "View.MemoryView":122 - * cdef bint dtype_is_object - * - * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< - * mode="c", bint allocate_buffer=True): - * - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_format); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":185 - * - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<< - * cdef int bufmode = -1 - * if self.mode == u"c": - */ - -/* Python wrapper */ -static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ -static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_v_bufmode; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - char *__pyx_t_4; - Py_ssize_t __pyx_t_5; - int __pyx_t_6; - Py_ssize_t *__pyx_t_7; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - if (__pyx_v_info == NULL) { - PyErr_SetString(PyExc_BufferError, "PyObject_GetBuffer: view==NULL argument is obsolete"); - return -1; - } - __Pyx_RefNannySetupContext("__getbuffer__", 0); - __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(__pyx_v_info->obj); - - /* "View.MemoryView":186 - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): - * cdef int bufmode = -1 # <<<<<<<<<<<<<< - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - */ - __pyx_v_bufmode = -1; - - /* "View.MemoryView":187 - * def __getbuffer__(self, Py_buffer *info, int flags): - * cdef int bufmode = -1 - * if self.mode == u"c": # <<<<<<<<<<<<<< - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": - */ - __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 187, __pyx_L1_error) - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":188 - * cdef int bufmode = -1 - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<< - * elif self.mode == u"fortran": - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - */ - __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS); - - /* "View.MemoryView":187 - * def __getbuffer__(self, Py_buffer *info, int flags): - * cdef int bufmode = -1 - * if self.mode == u"c": # <<<<<<<<<<<<<< - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": - */ - goto __pyx_L3; - } - - /* "View.MemoryView":189 - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": # <<<<<<<<<<<<<< - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): - */ - __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(2, 189, __pyx_L1_error) - __pyx_t_1 = (__pyx_t_2 != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":190 - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<< - * if not (flags & bufmode): - * raise ValueError("Can only create a buffer that is contiguous in memory.") - */ - __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS); - - /* "View.MemoryView":189 - * if self.mode == u"c": - * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * elif self.mode == u"fortran": # <<<<<<<<<<<<<< - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): - */ - } - __pyx_L3:; - - /* "View.MemoryView":191 - * elif self.mode == u"fortran": - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): # <<<<<<<<<<<<<< - * raise ValueError("Can only create a buffer that is contiguous in memory.") - * info.buf = self.data - */ - __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "View.MemoryView":192 - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): - * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<< - * info.buf = self.data - * info.len = self.len - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 192, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 192, __pyx_L1_error) - - /* "View.MemoryView":191 - * elif self.mode == u"fortran": - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): # <<<<<<<<<<<<<< - * raise ValueError("Can only create a buffer that is contiguous in memory.") - * info.buf = self.data - */ - } - - /* "View.MemoryView":193 - * if not (flags & bufmode): - * raise ValueError("Can only create a buffer that is contiguous in memory.") - * info.buf = self.data # <<<<<<<<<<<<<< - * info.len = self.len - * info.ndim = self.ndim - */ - __pyx_t_4 = __pyx_v_self->data; - __pyx_v_info->buf = __pyx_t_4; - - /* "View.MemoryView":194 - * raise ValueError("Can only create a buffer that is contiguous in memory.") - * info.buf = self.data - * info.len = self.len # <<<<<<<<<<<<<< - * info.ndim = self.ndim - * info.shape = self._shape - */ - __pyx_t_5 = __pyx_v_self->len; - __pyx_v_info->len = __pyx_t_5; - - /* "View.MemoryView":195 - * info.buf = self.data - * info.len = self.len - * info.ndim = self.ndim # <<<<<<<<<<<<<< - * info.shape = self._shape - * info.strides = self._strides - */ - __pyx_t_6 = __pyx_v_self->ndim; - __pyx_v_info->ndim = __pyx_t_6; - - /* "View.MemoryView":196 - * info.len = self.len - * info.ndim = self.ndim - * info.shape = self._shape # <<<<<<<<<<<<<< - * info.strides = self._strides - * info.suboffsets = NULL - */ - __pyx_t_7 = __pyx_v_self->_shape; - __pyx_v_info->shape = __pyx_t_7; - - /* "View.MemoryView":197 - * info.ndim = self.ndim - * info.shape = self._shape - * info.strides = self._strides # <<<<<<<<<<<<<< - * info.suboffsets = NULL - * info.itemsize = self.itemsize - */ - __pyx_t_7 = __pyx_v_self->_strides; - __pyx_v_info->strides = __pyx_t_7; - - /* "View.MemoryView":198 - * info.shape = self._shape - * info.strides = self._strides - * info.suboffsets = NULL # <<<<<<<<<<<<<< - * info.itemsize = self.itemsize - * info.readonly = 0 - */ - __pyx_v_info->suboffsets = NULL; - - /* "View.MemoryView":199 - * info.strides = self._strides - * info.suboffsets = NULL - * info.itemsize = self.itemsize # <<<<<<<<<<<<<< - * info.readonly = 0 - * - */ - __pyx_t_5 = __pyx_v_self->itemsize; - __pyx_v_info->itemsize = __pyx_t_5; - - /* "View.MemoryView":200 - * info.suboffsets = NULL - * info.itemsize = self.itemsize - * info.readonly = 0 # <<<<<<<<<<<<<< - * - * if flags & PyBUF_FORMAT: - */ - __pyx_v_info->readonly = 0; - - /* "View.MemoryView":202 - * info.readonly = 0 - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * info.format = self.format - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":203 - * - * if flags & PyBUF_FORMAT: - * info.format = self.format # <<<<<<<<<<<<<< - * else: - * info.format = NULL - */ - __pyx_t_4 = __pyx_v_self->format; - __pyx_v_info->format = __pyx_t_4; - - /* "View.MemoryView":202 - * info.readonly = 0 - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * info.format = self.format - * else: - */ - goto __pyx_L5; - } - - /* "View.MemoryView":205 - * info.format = self.format - * else: - * info.format = NULL # <<<<<<<<<<<<<< - * - * info.obj = self - */ - /*else*/ { - __pyx_v_info->format = NULL; - } - __pyx_L5:; - - /* "View.MemoryView":207 - * info.format = NULL - * - * info.obj = self # <<<<<<<<<<<<<< - * - * __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") - */ - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); - __pyx_v_info->obj = ((PyObject *)__pyx_v_self); - - /* "View.MemoryView":185 - * - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<< - * cdef int bufmode = -1 - * if self.mode == u"c": - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - if (__pyx_v_info->obj != NULL) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - goto __pyx_L2; - __pyx_L0:; - if (__pyx_v_info->obj == Py_None) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - __pyx_L2:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":211 - * __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") - * - * def __dealloc__(array self): # <<<<<<<<<<<<<< - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) - */ - -/* Python wrapper */ -static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_array___dealloc__(PyObject *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) { - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("__dealloc__", 0); - - /* "View.MemoryView":212 - * - * def __dealloc__(array self): - * if self.callback_free_data != NULL: # <<<<<<<<<<<<<< - * self.callback_free_data(self.data) - * elif self.free_data: - */ - __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":213 - * def __dealloc__(array self): - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) # <<<<<<<<<<<<<< - * elif self.free_data: - * if self.dtype_is_object: - */ - __pyx_v_self->callback_free_data(__pyx_v_self->data); - - /* "View.MemoryView":212 - * - * def __dealloc__(array self): - * if self.callback_free_data != NULL: # <<<<<<<<<<<<<< - * self.callback_free_data(self.data) - * elif self.free_data: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":214 - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) - * elif self.free_data: # <<<<<<<<<<<<<< - * if self.dtype_is_object: - * refcount_objects_in_slice(self.data, self._shape, - */ - __pyx_t_1 = (__pyx_v_self->free_data != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":215 - * self.callback_free_data(self.data) - * elif self.free_data: - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * refcount_objects_in_slice(self.data, self._shape, - * self._strides, self.ndim, False) - */ - __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":216 - * elif self.free_data: - * if self.dtype_is_object: - * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<< - * self._strides, self.ndim, False) - * free(self.data) - */ - __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0); - - /* "View.MemoryView":215 - * self.callback_free_data(self.data) - * elif self.free_data: - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * refcount_objects_in_slice(self.data, self._shape, - * self._strides, self.ndim, False) - */ - } - - /* "View.MemoryView":218 - * refcount_objects_in_slice(self.data, self._shape, - * self._strides, self.ndim, False) - * free(self.data) # <<<<<<<<<<<<<< - * PyObject_Free(self._shape) - * - */ - free(__pyx_v_self->data); - - /* "View.MemoryView":214 - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) - * elif self.free_data: # <<<<<<<<<<<<<< - * if self.dtype_is_object: - * refcount_objects_in_slice(self.data, self._shape, - */ - } - __pyx_L3:; - - /* "View.MemoryView":219 - * self._strides, self.ndim, False) - * free(self.data) - * PyObject_Free(self._shape) # <<<<<<<<<<<<<< - * - * @property - */ - PyObject_Free(__pyx_v_self->_shape); - - /* "View.MemoryView":211 - * __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") - * - * def __dealloc__(array self): # <<<<<<<<<<<<<< - * if self.callback_free_data != NULL: - * self.callback_free_data(self.data) - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "View.MemoryView":222 - * - * @property - * def memview(self): # <<<<<<<<<<<<<< - * return self.get_memview() - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "View.MemoryView":223 - * @property - * def memview(self): - * return self.get_memview() # <<<<<<<<<<<<<< - * - * @cname('get_memview') - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = ((struct __pyx_vtabstruct_array *)__pyx_v_self->__pyx_vtab)->get_memview(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 223, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "View.MemoryView":222 - * - * @property - * def memview(self): # <<<<<<<<<<<<<< - * return self.get_memview() - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":226 - * - * @cname('get_memview') - * cdef get_memview(self): # <<<<<<<<<<<<<< - * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE - * return memoryview(self, flags, self.dtype_is_object) - */ - -static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *__pyx_v_self) { - int __pyx_v_flags; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_memview", 0); - - /* "View.MemoryView":227 - * @cname('get_memview') - * cdef get_memview(self): - * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<< - * return memoryview(self, flags, self.dtype_is_object) - * - */ - __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE); - - /* "View.MemoryView":228 - * cdef get_memview(self): - * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE - * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<< - * - * def __len__(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 228, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 228, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 228, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); - PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self)); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 228, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":226 - * - * @cname('get_memview') - * cdef get_memview(self): # <<<<<<<<<<<<<< - * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE - * return memoryview(self, flags, self.dtype_is_object) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.array.get_memview", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":230 - * return memoryview(self, flags, self.dtype_is_object) - * - * def __len__(self): # <<<<<<<<<<<<<< - * return self._shape[0] - * - */ - -/* Python wrapper */ -static Py_ssize_t __pyx_array___len__(PyObject *__pyx_v_self); /*proto*/ -static Py_ssize_t __pyx_array___len__(PyObject *__pyx_v_self) { - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__len__(((struct __pyx_array_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static Py_ssize_t __pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__len__(struct __pyx_array_obj *__pyx_v_self) { - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__len__", 0); - - /* "View.MemoryView":231 - * - * def __len__(self): - * return self._shape[0] # <<<<<<<<<<<<<< - * - * def __getattr__(self, attr): - */ - __pyx_r = (__pyx_v_self->_shape[0]); - goto __pyx_L0; - - /* "View.MemoryView":230 - * return memoryview(self, flags, self.dtype_is_object) - * - * def __len__(self): # <<<<<<<<<<<<<< - * return self._shape[0] - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":233 - * return self._shape[0] - * - * def __getattr__(self, attr): # <<<<<<<<<<<<<< - * return getattr(self.memview, attr) - * - */ - -/* Python wrapper */ -static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/ -static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__getattr__", 0); - - /* "View.MemoryView":234 - * - * def __getattr__(self, attr): - * return getattr(self.memview, attr) # <<<<<<<<<<<<<< - * - * def __getitem__(self, item): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 234, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 234, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":233 - * return self._shape[0] - * - * def __getattr__(self, attr): # <<<<<<<<<<<<<< - * return getattr(self.memview, attr) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":236 - * return getattr(self.memview, attr) - * - * def __getitem__(self, item): # <<<<<<<<<<<<<< - * return self.memview[item] - * - */ - -/* Python wrapper */ -static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ -static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__getitem__", 0); - - /* "View.MemoryView":237 - * - * def __getitem__(self, item): - * return self.memview[item] # <<<<<<<<<<<<<< - * - * def __setitem__(self, item, value): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":236 - * return getattr(self.memview, attr) - * - * def __getitem__(self, item): # <<<<<<<<<<<<<< - * return self.memview[item] - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":239 - * return self.memview[item] - * - * def __setitem__(self, item, value): # <<<<<<<<<<<<<< - * self.memview[item] = value - * - */ - -/* Python wrapper */ -static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/ -static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); - __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_12__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_12__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setitem__", 0); - - /* "View.MemoryView":240 - * - * def __setitem__(self, item, value): - * self.memview[item] = value # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 240, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) __PYX_ERR(2, 240, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "View.MemoryView":239 - * return self.memview[item] - * - * def __setitem__(self, item, value): # <<<<<<<<<<<<<< - * self.memview[item] = value - * - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_array_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw___pyx_array_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_array___reduce_cython__(((struct __pyx_array_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_array___reduce_cython__(CYTHON_UNUSED struct __pyx_array_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.array.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_array_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw___pyx_array_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_array_2__setstate_cython__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_array_2__setstate_cython__(CYTHON_UNUSED struct __pyx_array_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.array.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":244 - * - * @cname("__pyx_array_new") - * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<< - * char *mode, char *buf): - * cdef array result - */ - -static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) { - struct __pyx_array_obj *__pyx_v_result = 0; - struct __pyx_array_obj *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("array_cwrapper", 0); - - /* "View.MemoryView":248 - * cdef array result - * - * if buf == NULL: # <<<<<<<<<<<<<< - * result = array(shape, itemsize, format, mode.decode('ASCII')) - * else: - */ - __pyx_t_1 = ((__pyx_v_buf == NULL) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":249 - * - * if buf == NULL: - * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<< - * else: - * result = array(shape, itemsize, format, mode.decode('ASCII'), - */ - __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 249, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 249, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 249, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 249, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_INCREF(__pyx_v_shape); - __Pyx_GIVEREF(__pyx_v_shape); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4); - __pyx_t_2 = 0; - __pyx_t_3 = 0; - __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_array_type), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 249, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4); - __pyx_t_4 = 0; - - /* "View.MemoryView":248 - * cdef array result - * - * if buf == NULL: # <<<<<<<<<<<<<< - * result = array(shape, itemsize, format, mode.decode('ASCII')) - * else: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":251 - * result = array(shape, itemsize, format, mode.decode('ASCII')) - * else: - * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<< - * allocate_buffer=False) - * result.data = buf - */ - /*else*/ { - __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 251, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 251, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 251, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 251, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_v_shape); - __Pyx_GIVEREF(__pyx_v_shape); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3); - __pyx_t_4 = 0; - __pyx_t_5 = 0; - __pyx_t_3 = 0; - - /* "View.MemoryView":252 - * else: - * result = array(shape, itemsize, format, mode.decode('ASCII'), - * allocate_buffer=False) # <<<<<<<<<<<<<< - * result.data = buf - * - */ - __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 252, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) __PYX_ERR(2, 252, __pyx_L1_error) - - /* "View.MemoryView":251 - * result = array(shape, itemsize, format, mode.decode('ASCII')) - * else: - * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<< - * allocate_buffer=False) - * result.data = buf - */ - __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)__pyx_array_type), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 251, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5); - __pyx_t_5 = 0; - - /* "View.MemoryView":253 - * result = array(shape, itemsize, format, mode.decode('ASCII'), - * allocate_buffer=False) - * result.data = buf # <<<<<<<<<<<<<< - * - * return result - */ - __pyx_v_result->data = __pyx_v_buf; - } - __pyx_L3:; - - /* "View.MemoryView":255 - * result.data = buf - * - * return result # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(((PyObject *)__pyx_r)); - __Pyx_INCREF(((PyObject *)__pyx_v_result)); - __pyx_r = __pyx_v_result; - goto __pyx_L0; - - /* "View.MemoryView":244 - * - * @cname("__pyx_array_new") - * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<< - * char *mode, char *buf): - * cdef array result - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_result); - __Pyx_XGIVEREF((PyObject *)__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":281 - * cdef class Enum(object): - * cdef object name - * def __init__(self, name): # <<<<<<<<<<<<<< - * self.name = name - * def __repr__(self): - */ - -/* Python wrapper */ -static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_name = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0}; - PyObject* values[1] = {0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(2, 281, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - } - __pyx_v_name = values[0]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(2, 281, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__init__", 0); - - /* "View.MemoryView":282 - * cdef object name - * def __init__(self, name): - * self.name = name # <<<<<<<<<<<<<< - * def __repr__(self): - * return self.name - */ - __Pyx_INCREF(__pyx_v_name); - __Pyx_GIVEREF(__pyx_v_name); - __Pyx_GOTREF(__pyx_v_self->name); - __Pyx_DECREF(__pyx_v_self->name); - __pyx_v_self->name = __pyx_v_name; - - /* "View.MemoryView":281 - * cdef class Enum(object): - * cdef object name - * def __init__(self, name): # <<<<<<<<<<<<<< - * self.name = name - * def __repr__(self): - */ - - /* function exit code */ - __pyx_r = 0; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":283 - * def __init__(self, name): - * self.name = name - * def __repr__(self): # <<<<<<<<<<<<<< - * return self.name - * - */ - -/* Python wrapper */ -static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); - __pyx_r = __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__repr__", 0); - - /* "View.MemoryView":284 - * self.name = name - * def __repr__(self): - * return self.name # <<<<<<<<<<<<<< - * - * cdef generic = Enum("") - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->name); - __pyx_r = __pyx_v_self->name; - goto __pyx_L0; - - /* "View.MemoryView":283 - * def __init__(self, name): - * self.name = name - * def __repr__(self): # <<<<<<<<<<<<<< - * return self.name - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_MemviewEnum_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw___pyx_MemviewEnum_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_MemviewEnum___reduce_cython__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_MemviewEnum___reduce_cython__(struct __pyx_MemviewEnum_obj *__pyx_v_self) { - PyObject *__pyx_v_state = 0; - PyObject *__pyx_v__dict = 0; - int __pyx_v_use_setstate; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":5 - * cdef object _dict - * cdef bint use_setstate - * state = (self.name,) # <<<<<<<<<<<<<< - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - */ - __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_self->name); - __Pyx_GIVEREF(__pyx_v_self->name); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->name); - __pyx_v_state = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "(tree fragment)":6 - * cdef bint use_setstate - * state = (self.name,) - * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< - * if _dict is not None: - * state += (_dict,) - */ - __pyx_t_1 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v__dict = __pyx_t_1; - __pyx_t_1 = 0; - - /* "(tree fragment)":7 - * state = (self.name,) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - __pyx_t_2 = (__pyx_v__dict != Py_None); - __pyx_t_3 = (__pyx_t_2 != 0); - if (__pyx_t_3) { - - /* "(tree fragment)":8 - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: - * state += (_dict,) # <<<<<<<<<<<<<< - * use_setstate = True - * else: - */ - __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v__dict); - __Pyx_GIVEREF(__pyx_v__dict); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v__dict); - __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_4)); - __pyx_t_4 = 0; - - /* "(tree fragment)":9 - * if _dict is not None: - * state += (_dict,) - * use_setstate = True # <<<<<<<<<<<<<< - * else: - * use_setstate = self.name is not None - */ - __pyx_v_use_setstate = 1; - - /* "(tree fragment)":7 - * state = (self.name,) - * _dict = getattr(self, '__dict__', None) - * if _dict is not None: # <<<<<<<<<<<<<< - * state += (_dict,) - * use_setstate = True - */ - goto __pyx_L3; - } - - /* "(tree fragment)":11 - * use_setstate = True - * else: - * use_setstate = self.name is not None # <<<<<<<<<<<<<< - * if use_setstate: - * return __pyx_unpickle_Enum, (type(self), 0xb068931, None), state - */ - /*else*/ { - __pyx_t_3 = (__pyx_v_self->name != Py_None); - __pyx_v_use_setstate = __pyx_t_3; - } - __pyx_L3:; - - /* "(tree fragment)":12 - * else: - * use_setstate = self.name is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_Enum, (type(self), 0xb068931, None), state - * else: - */ - __pyx_t_3 = (__pyx_v_use_setstate != 0); - if (__pyx_t_3) { - - /* "(tree fragment)":13 - * use_setstate = self.name is not None - * if use_setstate: - * return __pyx_unpickle_Enum, (type(self), 0xb068931, None), state # <<<<<<<<<<<<<< - * else: - * return __pyx_unpickle_Enum, (type(self), 0xb068931, state) - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pyx_unpickle_Enum); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_INCREF(__pyx_int_184977713); - __Pyx_GIVEREF(__pyx_int_184977713); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_184977713); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_1, 2, Py_None); - __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 13, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_1); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_state); - __pyx_t_4 = 0; - __pyx_t_1 = 0; - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; - goto __pyx_L0; - - /* "(tree fragment)":12 - * else: - * use_setstate = self.name is not None - * if use_setstate: # <<<<<<<<<<<<<< - * return __pyx_unpickle_Enum, (type(self), 0xb068931, None), state - * else: - */ - } - - /* "(tree fragment)":15 - * return __pyx_unpickle_Enum, (type(self), 0xb068931, None), state - * else: - * return __pyx_unpickle_Enum, (type(self), 0xb068931, state) # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_Enum__set_state(self, __pyx_state) - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_pyx_unpickle_Enum); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); - __Pyx_INCREF(__pyx_int_184977713); - __Pyx_GIVEREF(__pyx_int_184977713); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_184977713); - __Pyx_INCREF(__pyx_v_state); - __Pyx_GIVEREF(__pyx_v_state); - PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_state); - __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 15, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1); - __pyx_t_5 = 0; - __pyx_t_1 = 0; - __pyx_r = __pyx_t_4; - __pyx_t_4 = 0; - goto __pyx_L0; - } - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * cdef tuple state - * cdef object _dict - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.Enum.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_state); - __Pyx_XDECREF(__pyx_v__dict); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":16 - * else: - * return __pyx_unpickle_Enum, (type(self), 0xb068931, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_Enum__set_state(self, __pyx_state) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_MemviewEnum_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw___pyx_MemviewEnum_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_MemviewEnum_2__setstate_cython__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_MemviewEnum_2__setstate_cython__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":17 - * return __pyx_unpickle_Enum, (type(self), 0xb068931, state) - * def __setstate_cython__(self, __pyx_state): - * __pyx_unpickle_Enum__set_state(self, __pyx_state) # <<<<<<<<<<<<<< - */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(2, 17, __pyx_L1_error) - __pyx_t_1 = __pyx_unpickle_Enum__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 17, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":16 - * else: - * return __pyx_unpickle_Enum, (type(self), 0xb068931, state) - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * __pyx_unpickle_Enum__set_state(self, __pyx_state) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.Enum.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":298 - * - * @cname('__pyx_align_pointer') - * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<< - * "Align pointer memory on a given boundary" - * cdef Py_intptr_t aligned_p = memory - */ - -static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) { - Py_intptr_t __pyx_v_aligned_p; - size_t __pyx_v_offset; - void *__pyx_r; - int __pyx_t_1; - - /* "View.MemoryView":300 - * cdef void *align_pointer(void *memory, size_t alignment) nogil: - * "Align pointer memory on a given boundary" - * cdef Py_intptr_t aligned_p = memory # <<<<<<<<<<<<<< - * cdef size_t offset - * - */ - __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory); - - /* "View.MemoryView":304 - * - * with cython.cdivision(True): - * offset = aligned_p % alignment # <<<<<<<<<<<<<< - * - * if offset > 0: - */ - __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment); - - /* "View.MemoryView":306 - * offset = aligned_p % alignment - * - * if offset > 0: # <<<<<<<<<<<<<< - * aligned_p += alignment - offset - * - */ - __pyx_t_1 = ((__pyx_v_offset > 0) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":307 - * - * if offset > 0: - * aligned_p += alignment - offset # <<<<<<<<<<<<<< - * - * return aligned_p - */ - __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset)); - - /* "View.MemoryView":306 - * offset = aligned_p % alignment - * - * if offset > 0: # <<<<<<<<<<<<<< - * aligned_p += alignment - offset - * - */ - } - - /* "View.MemoryView":309 - * aligned_p += alignment - offset - * - * return aligned_p # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = ((void *)__pyx_v_aligned_p); - goto __pyx_L0; - - /* "View.MemoryView":298 - * - * @cname('__pyx_align_pointer') - * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<< - * "Align pointer memory on a given boundary" - * cdef Py_intptr_t aligned_p = memory - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":345 - * cdef __Pyx_TypeInfo *typeinfo - * - * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<< - * self.obj = obj - * self.flags = flags - */ - -/* Python wrapper */ -static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_obj = 0; - int __pyx_v_flags; - int __pyx_v_dtype_is_object; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0}; - PyObject* values[3] = {0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); __PYX_ERR(2, 345, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_dtype_is_object); - if (value) { values[2] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(2, 345, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_obj = values[0]; - __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 345, __pyx_L3_error) - if (values[2]) { - __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 345, __pyx_L3_error) - } else { - __pyx_v_dtype_is_object = ((int)0); - } - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(2, 345, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__cinit__", 0); - - /* "View.MemoryView":346 - * - * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): - * self.obj = obj # <<<<<<<<<<<<<< - * self.flags = flags - * if type(self) is memoryview or obj is not None: - */ - __Pyx_INCREF(__pyx_v_obj); - __Pyx_GIVEREF(__pyx_v_obj); - __Pyx_GOTREF(__pyx_v_self->obj); - __Pyx_DECREF(__pyx_v_self->obj); - __pyx_v_self->obj = __pyx_v_obj; - - /* "View.MemoryView":347 - * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): - * self.obj = obj - * self.flags = flags # <<<<<<<<<<<<<< - * if type(self) is memoryview or obj is not None: - * __Pyx_GetBuffer(obj, &self.view, flags) - */ - __pyx_v_self->flags = __pyx_v_flags; - - /* "View.MemoryView":348 - * self.obj = obj - * self.flags = flags - * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<< - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: - */ - __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)__pyx_memoryview_type)); - __pyx_t_3 = (__pyx_t_2 != 0); - if (!__pyx_t_3) { - } else { - __pyx_t_1 = __pyx_t_3; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_3 = (__pyx_v_obj != Py_None); - __pyx_t_2 = (__pyx_t_3 != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L4_bool_binop_done:; - if (__pyx_t_1) { - - /* "View.MemoryView":349 - * self.flags = flags - * if type(self) is memoryview or obj is not None: - * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<< - * if self.view.obj == NULL: - * (<__pyx_buffer *> &self.view).obj = Py_None - */ - __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 349, __pyx_L1_error) - - /* "View.MemoryView":350 - * if type(self) is memoryview or obj is not None: - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: # <<<<<<<<<<<<<< - * (<__pyx_buffer *> &self.view).obj = Py_None - * Py_INCREF(Py_None) - */ - __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":351 - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: - * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<< - * Py_INCREF(Py_None) - * - */ - ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None; - - /* "View.MemoryView":352 - * if self.view.obj == NULL: - * (<__pyx_buffer *> &self.view).obj = Py_None - * Py_INCREF(Py_None) # <<<<<<<<<<<<<< - * - * global __pyx_memoryview_thread_locks_used - */ - Py_INCREF(Py_None); - - /* "View.MemoryView":350 - * if type(self) is memoryview or obj is not None: - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: # <<<<<<<<<<<<<< - * (<__pyx_buffer *> &self.view).obj = Py_None - * Py_INCREF(Py_None) - */ - } - - /* "View.MemoryView":348 - * self.obj = obj - * self.flags = flags - * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<< - * __Pyx_GetBuffer(obj, &self.view, flags) - * if self.view.obj == NULL: - */ - } - - /* "View.MemoryView":355 - * - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: # <<<<<<<<<<<<<< - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 - */ - __pyx_t_1 = ((__pyx_memoryview_thread_locks_used < 8) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":356 - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks_used += 1 - * if self.lock is NULL: - */ - __pyx_v_self->lock = (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]); - - /* "View.MemoryView":357 - * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 # <<<<<<<<<<<<<< - * if self.lock is NULL: - * self.lock = PyThread_allocate_lock() - */ - __pyx_memoryview_thread_locks_used = (__pyx_memoryview_thread_locks_used + 1); - - /* "View.MemoryView":355 - * - * global __pyx_memoryview_thread_locks_used - * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: # <<<<<<<<<<<<<< - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 - */ - } - - /* "View.MemoryView":358 - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 - * if self.lock is NULL: # <<<<<<<<<<<<<< - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: - */ - __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":359 - * __pyx_memoryview_thread_locks_used += 1 - * if self.lock is NULL: - * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<< - * if self.lock is NULL: - * raise MemoryError - */ - __pyx_v_self->lock = PyThread_allocate_lock(); - - /* "View.MemoryView":360 - * if self.lock is NULL: - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: # <<<<<<<<<<<<<< - * raise MemoryError - * - */ - __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0); - if (unlikely(__pyx_t_1)) { - - /* "View.MemoryView":361 - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: - * raise MemoryError # <<<<<<<<<<<<<< - * - * if flags & PyBUF_FORMAT: - */ - PyErr_NoMemory(); __PYX_ERR(2, 361, __pyx_L1_error) - - /* "View.MemoryView":360 - * if self.lock is NULL: - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: # <<<<<<<<<<<<<< - * raise MemoryError - * - */ - } - - /* "View.MemoryView":358 - * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] - * __pyx_memoryview_thread_locks_used += 1 - * if self.lock is NULL: # <<<<<<<<<<<<<< - * self.lock = PyThread_allocate_lock() - * if self.lock is NULL: - */ - } - - /* "View.MemoryView":363 - * raise MemoryError - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":364 - * - * if flags & PyBUF_FORMAT: - * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') # <<<<<<<<<<<<<< - * else: - * self.dtype_is_object = dtype_is_object - */ - __pyx_t_2 = (((__pyx_v_self->view.format[0]) == 'O') != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L11_bool_binop_done; - } - __pyx_t_2 = (((__pyx_v_self->view.format[1]) == '\x00') != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L11_bool_binop_done:; - __pyx_v_self->dtype_is_object = __pyx_t_1; - - /* "View.MemoryView":363 - * raise MemoryError - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') - * else: - */ - goto __pyx_L10; - } - - /* "View.MemoryView":366 - * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') - * else: - * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<< - * - * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( - */ - /*else*/ { - __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object; - } - __pyx_L10:; - - /* "View.MemoryView":368 - * self.dtype_is_object = dtype_is_object - * - * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<< - * &self.acquisition_count[0], sizeof(__pyx_atomic_int)) - * self.typeinfo = NULL - */ - __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int)))); - - /* "View.MemoryView":370 - * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( - * &self.acquisition_count[0], sizeof(__pyx_atomic_int)) - * self.typeinfo = NULL # <<<<<<<<<<<<<< - * - * def __dealloc__(memoryview self): - */ - __pyx_v_self->typeinfo = NULL; - - /* "View.MemoryView":345 - * cdef __Pyx_TypeInfo *typeinfo - * - * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<< - * self.obj = obj - * self.flags = flags - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":372 - * self.typeinfo = NULL - * - * def __dealloc__(memoryview self): # <<<<<<<<<<<<<< - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) - */ - -/* Python wrapper */ -static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) { - int __pyx_v_i; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - PyThread_type_lock __pyx_t_6; - PyThread_type_lock __pyx_t_7; - __Pyx_RefNannySetupContext("__dealloc__", 0); - - /* "View.MemoryView":373 - * - * def __dealloc__(memoryview self): - * if self.obj is not None: # <<<<<<<<<<<<<< - * __Pyx_ReleaseBuffer(&self.view) - * elif (<__pyx_buffer *> &self.view).obj == Py_None: - */ - __pyx_t_1 = (__pyx_v_self->obj != Py_None); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":374 - * def __dealloc__(memoryview self): - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<< - * elif (<__pyx_buffer *> &self.view).obj == Py_None: - * - */ - __Pyx_ReleaseBuffer((&__pyx_v_self->view)); - - /* "View.MemoryView":373 - * - * def __dealloc__(memoryview self): - * if self.obj is not None: # <<<<<<<<<<<<<< - * __Pyx_ReleaseBuffer(&self.view) - * elif (<__pyx_buffer *> &self.view).obj == Py_None: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":375 - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) - * elif (<__pyx_buffer *> &self.view).obj == Py_None: # <<<<<<<<<<<<<< - * - * (<__pyx_buffer *> &self.view).obj = NULL - */ - __pyx_t_2 = ((((Py_buffer *)(&__pyx_v_self->view))->obj == Py_None) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":377 - * elif (<__pyx_buffer *> &self.view).obj == Py_None: - * - * (<__pyx_buffer *> &self.view).obj = NULL # <<<<<<<<<<<<<< - * Py_DECREF(Py_None) - * - */ - ((Py_buffer *)(&__pyx_v_self->view))->obj = NULL; - - /* "View.MemoryView":378 - * - * (<__pyx_buffer *> &self.view).obj = NULL - * Py_DECREF(Py_None) # <<<<<<<<<<<<<< - * - * cdef int i - */ - Py_DECREF(Py_None); - - /* "View.MemoryView":375 - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) - * elif (<__pyx_buffer *> &self.view).obj == Py_None: # <<<<<<<<<<<<<< - * - * (<__pyx_buffer *> &self.view).obj = NULL - */ - } - __pyx_L3:; - - /* "View.MemoryView":382 - * cdef int i - * global __pyx_memoryview_thread_locks_used - * if self.lock != NULL: # <<<<<<<<<<<<<< - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: - */ - __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":383 - * global __pyx_memoryview_thread_locks_used - * if self.lock != NULL: - * for i in range(__pyx_memoryview_thread_locks_used): # <<<<<<<<<<<<<< - * if __pyx_memoryview_thread_locks[i] is self.lock: - * __pyx_memoryview_thread_locks_used -= 1 - */ - __pyx_t_3 = __pyx_memoryview_thread_locks_used; - __pyx_t_4 = __pyx_t_3; - for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { - __pyx_v_i = __pyx_t_5; - - /* "View.MemoryView":384 - * if self.lock != NULL: - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: - */ - __pyx_t_2 = (((__pyx_memoryview_thread_locks[__pyx_v_i]) == __pyx_v_self->lock) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":385 - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: - * __pyx_memoryview_thread_locks_used -= 1 # <<<<<<<<<<<<<< - * if i != __pyx_memoryview_thread_locks_used: - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - */ - __pyx_memoryview_thread_locks_used = (__pyx_memoryview_thread_locks_used - 1); - - /* "View.MemoryView":386 - * if __pyx_memoryview_thread_locks[i] is self.lock: - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) - */ - __pyx_t_2 = ((__pyx_v_i != __pyx_memoryview_thread_locks_used) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":388 - * if i != __pyx_memoryview_thread_locks_used: - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) # <<<<<<<<<<<<<< - * break - * else: - */ - __pyx_t_6 = (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]); - __pyx_t_7 = (__pyx_memoryview_thread_locks[__pyx_v_i]); - - /* "View.MemoryView":387 - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) - * break - */ - (__pyx_memoryview_thread_locks[__pyx_v_i]) = __pyx_t_6; - (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]) = __pyx_t_7; - - /* "View.MemoryView":386 - * if __pyx_memoryview_thread_locks[i] is self.lock: - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) - */ - } - - /* "View.MemoryView":389 - * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( - * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) - * break # <<<<<<<<<<<<<< - * else: - * PyThread_free_lock(self.lock) - */ - goto __pyx_L6_break; - - /* "View.MemoryView":384 - * if self.lock != NULL: - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: # <<<<<<<<<<<<<< - * __pyx_memoryview_thread_locks_used -= 1 - * if i != __pyx_memoryview_thread_locks_used: - */ - } - } - /*else*/ { - - /* "View.MemoryView":391 - * break - * else: - * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<< - * - * cdef char *get_item_pointer(memoryview self, object index) except NULL: - */ - PyThread_free_lock(__pyx_v_self->lock); - } - __pyx_L6_break:; - - /* "View.MemoryView":382 - * cdef int i - * global __pyx_memoryview_thread_locks_used - * if self.lock != NULL: # <<<<<<<<<<<<<< - * for i in range(__pyx_memoryview_thread_locks_used): - * if __pyx_memoryview_thread_locks[i] is self.lock: - */ - } - - /* "View.MemoryView":372 - * self.typeinfo = NULL - * - * def __dealloc__(memoryview self): # <<<<<<<<<<<<<< - * if self.obj is not None: - * __Pyx_ReleaseBuffer(&self.view) - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "View.MemoryView":393 - * PyThread_free_lock(self.lock) - * - * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<< - * cdef Py_ssize_t dim - * cdef char *itemp = self.view.buf - */ - -static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) { - Py_ssize_t __pyx_v_dim; - char *__pyx_v_itemp; - PyObject *__pyx_v_idx = NULL; - char *__pyx_r; - __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - Py_ssize_t __pyx_t_3; - PyObject *(*__pyx_t_4)(PyObject *); - PyObject *__pyx_t_5 = NULL; - Py_ssize_t __pyx_t_6; - char *__pyx_t_7; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_item_pointer", 0); - - /* "View.MemoryView":395 - * cdef char *get_item_pointer(memoryview self, object index) except NULL: - * cdef Py_ssize_t dim - * cdef char *itemp = self.view.buf # <<<<<<<<<<<<<< - * - * for dim, idx in enumerate(index): - */ - __pyx_v_itemp = ((char *)__pyx_v_self->view.buf); - - /* "View.MemoryView":397 - * cdef char *itemp = self.view.buf - * - * for dim, idx in enumerate(index): # <<<<<<<<<<<<<< - * itemp = pybuffer_index(&self.view, itemp, idx, dim) - * - */ - __pyx_t_1 = 0; - if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) { - __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0; - __pyx_t_4 = NULL; - } else { - __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 397, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 397, __pyx_L1_error) - } - for (;;) { - if (likely(!__pyx_t_4)) { - if (likely(PyList_CheckExact(__pyx_t_2))) { - if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(2, 397, __pyx_L1_error) - #else - __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 397, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - } else { - if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(2, 397, __pyx_L1_error) - #else - __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 397, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - } - } else { - __pyx_t_5 = __pyx_t_4(__pyx_t_2); - if (unlikely(!__pyx_t_5)) { - PyObject* exc_type = PyErr_Occurred(); - if (exc_type) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); - else __PYX_ERR(2, 397, __pyx_L1_error) - } - break; - } - __Pyx_GOTREF(__pyx_t_5); - } - __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5); - __pyx_t_5 = 0; - __pyx_v_dim = __pyx_t_1; - __pyx_t_1 = (__pyx_t_1 + 1); - - /* "View.MemoryView":398 - * - * for dim, idx in enumerate(index): - * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<< - * - * return itemp - */ - __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 398, __pyx_L1_error) - __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == ((char *)NULL))) __PYX_ERR(2, 398, __pyx_L1_error) - __pyx_v_itemp = __pyx_t_7; - - /* "View.MemoryView":397 - * cdef char *itemp = self.view.buf - * - * for dim, idx in enumerate(index): # <<<<<<<<<<<<<< - * itemp = pybuffer_index(&self.view, itemp, idx, dim) - * - */ - } - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "View.MemoryView":400 - * itemp = pybuffer_index(&self.view, itemp, idx, dim) - * - * return itemp # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_itemp; - goto __pyx_L0; - - /* "View.MemoryView":393 - * PyThread_free_lock(self.lock) - * - * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<< - * cdef Py_ssize_t dim - * cdef char *itemp = self.view.buf - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_idx); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":403 - * - * - * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<< - * if index is Ellipsis: - * return self - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/ -static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) { - PyObject *__pyx_v_have_slices = NULL; - PyObject *__pyx_v_indices = NULL; - char *__pyx_v_itemp; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - char *__pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__getitem__", 0); - - /* "View.MemoryView":404 - * - * def __getitem__(memoryview self, object index): - * if index is Ellipsis: # <<<<<<<<<<<<<< - * return self - * - */ - __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":405 - * def __getitem__(memoryview self, object index): - * if index is Ellipsis: - * return self # <<<<<<<<<<<<<< - * - * have_slices, indices = _unellipsify(index, self.view.ndim) - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __pyx_r = ((PyObject *)__pyx_v_self); - goto __pyx_L0; - - /* "View.MemoryView":404 - * - * def __getitem__(memoryview self, object index): - * if index is Ellipsis: # <<<<<<<<<<<<<< - * return self - * - */ - } - - /* "View.MemoryView":407 - * return self - * - * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<< - * - * cdef char *itemp - */ - __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 407, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (likely(__pyx_t_3 != Py_None)) { - PyObject* sequence = __pyx_t_3; - Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); - if (unlikely(size != 2)) { - if (size > 2) __Pyx_RaiseTooManyValuesError(2); - else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(2, 407, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - #else - __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 407, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 407, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - #endif - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(2, 407, __pyx_L1_error) - } - __pyx_v_have_slices = __pyx_t_4; - __pyx_t_4 = 0; - __pyx_v_indices = __pyx_t_5; - __pyx_t_5 = 0; - - /* "View.MemoryView":410 - * - * cdef char *itemp - * if have_slices: # <<<<<<<<<<<<<< - * return memview_slice(self, indices) - * else: - */ - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(2, 410, __pyx_L1_error) - if (__pyx_t_2) { - - /* "View.MemoryView":411 - * cdef char *itemp - * if have_slices: - * return memview_slice(self, indices) # <<<<<<<<<<<<<< - * else: - * itemp = self.get_item_pointer(indices) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 411, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "View.MemoryView":410 - * - * cdef char *itemp - * if have_slices: # <<<<<<<<<<<<<< - * return memview_slice(self, indices) - * else: - */ - } - - /* "View.MemoryView":413 - * return memview_slice(self, indices) - * else: - * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<< - * return self.convert_item_to_object(itemp) - * - */ - /*else*/ { - __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == ((char *)NULL))) __PYX_ERR(2, 413, __pyx_L1_error) - __pyx_v_itemp = __pyx_t_6; - - /* "View.MemoryView":414 - * else: - * itemp = self.get_item_pointer(indices) - * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<< - * - * def __setitem__(memoryview self, object index, object value): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 414, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - } - - /* "View.MemoryView":403 - * - * - * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<< - * if index is Ellipsis: - * return self - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_have_slices); - __Pyx_XDECREF(__pyx_v_indices); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":416 - * return self.convert_item_to_object(itemp) - * - * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<< - * if self.view.readonly: - * raise TypeError("Cannot assign to read-only memoryview") - */ - -/* Python wrapper */ -static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/ -static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { - PyObject *__pyx_v_have_slices = NULL; - PyObject *__pyx_v_obj = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setitem__", 0); - __Pyx_INCREF(__pyx_v_index); - - /* "View.MemoryView":417 - * - * def __setitem__(memoryview self, object index, object value): - * if self.view.readonly: # <<<<<<<<<<<<<< - * raise TypeError("Cannot assign to read-only memoryview") - * - */ - __pyx_t_1 = (__pyx_v_self->view.readonly != 0); - if (unlikely(__pyx_t_1)) { - - /* "View.MemoryView":418 - * def __setitem__(memoryview self, object index, object value): - * if self.view.readonly: - * raise TypeError("Cannot assign to read-only memoryview") # <<<<<<<<<<<<<< - * - * have_slices, index = _unellipsify(index, self.view.ndim) - */ - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 418, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(2, 418, __pyx_L1_error) - - /* "View.MemoryView":417 - * - * def __setitem__(memoryview self, object index, object value): - * if self.view.readonly: # <<<<<<<<<<<<<< - * raise TypeError("Cannot assign to read-only memoryview") - * - */ - } - - /* "View.MemoryView":420 - * raise TypeError("Cannot assign to read-only memoryview") - * - * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<< - * - * if have_slices: - */ - __pyx_t_2 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 420, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (likely(__pyx_t_2 != Py_None)) { - PyObject* sequence = __pyx_t_2; - Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); - if (unlikely(size != 2)) { - if (size > 2) __Pyx_RaiseTooManyValuesError(2); - else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(2, 420, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - #else - __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 420, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 420, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - #endif - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - } else { - __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(2, 420, __pyx_L1_error) - } - __pyx_v_have_slices = __pyx_t_3; - __pyx_t_3 = 0; - __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_4); - __pyx_t_4 = 0; - - /* "View.MemoryView":422 - * have_slices, index = _unellipsify(index, self.view.ndim) - * - * if have_slices: # <<<<<<<<<<<<<< - * obj = self.is_slice(value) - * if obj: - */ - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 422, __pyx_L1_error) - if (__pyx_t_1) { - - /* "View.MemoryView":423 - * - * if have_slices: - * obj = self.is_slice(value) # <<<<<<<<<<<<<< - * if obj: - * self.setitem_slice_assignment(self[index], obj) - */ - __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 423, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_v_obj = __pyx_t_2; - __pyx_t_2 = 0; - - /* "View.MemoryView":424 - * if have_slices: - * obj = self.is_slice(value) - * if obj: # <<<<<<<<<<<<<< - * self.setitem_slice_assignment(self[index], obj) - * else: - */ - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 424, __pyx_L1_error) - if (__pyx_t_1) { - - /* "View.MemoryView":425 - * obj = self.is_slice(value) - * if obj: - * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<< - * else: - * self.setitem_slice_assign_scalar(self[index], value) - */ - __pyx_t_2 = __Pyx_PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 425, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_2, __pyx_v_obj); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 425, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "View.MemoryView":424 - * if have_slices: - * obj = self.is_slice(value) - * if obj: # <<<<<<<<<<<<<< - * self.setitem_slice_assignment(self[index], obj) - * else: - */ - goto __pyx_L5; - } - - /* "View.MemoryView":427 - * self.setitem_slice_assignment(self[index], obj) - * else: - * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<< - * else: - * self.setitem_indexed(index, value) - */ - /*else*/ { - __pyx_t_4 = __Pyx_PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 427, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_memoryview_type))))) __PYX_ERR(2, 427, __pyx_L1_error) - __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_4), __pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 427, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - } - __pyx_L5:; - - /* "View.MemoryView":422 - * have_slices, index = _unellipsify(index, self.view.ndim) - * - * if have_slices: # <<<<<<<<<<<<<< - * obj = self.is_slice(value) - * if obj: - */ - goto __pyx_L4; - } - - /* "View.MemoryView":429 - * self.setitem_slice_assign_scalar(self[index], value) - * else: - * self.setitem_indexed(index, value) # <<<<<<<<<<<<<< - * - * cdef is_slice(self, obj): - */ - /*else*/ { - __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 429, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - } - __pyx_L4:; - - /* "View.MemoryView":416 - * return self.convert_item_to_object(itemp) - * - * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<< - * if self.view.readonly: - * raise TypeError("Cannot assign to read-only memoryview") - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_have_slices); - __Pyx_XDECREF(__pyx_v_obj); - __Pyx_XDECREF(__pyx_v_index); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":431 - * self.setitem_indexed(index, value) - * - * cdef is_slice(self, obj): # <<<<<<<<<<<<<< - * if not isinstance(obj, memoryview): - * try: - */ - -static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_t_9; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("is_slice", 0); - __Pyx_INCREF(__pyx_v_obj); - - /* "View.MemoryView":432 - * - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<< - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - */ - __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, __pyx_memoryview_type); - __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":433 - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): - * try: # <<<<<<<<<<<<<< - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_5); - /*try:*/ { - - /* "View.MemoryView":434 - * if not isinstance(obj, memoryview): - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<< - * self.dtype_is_object) - * except TypeError: - */ - __pyx_t_6 = __Pyx_PyInt_From_int(((__pyx_v_self->flags & (~PyBUF_WRITABLE)) | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 434, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - - /* "View.MemoryView":435 - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) # <<<<<<<<<<<<<< - * except TypeError: - * return None - */ - __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 435, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_7); - - /* "View.MemoryView":434 - * if not isinstance(obj, memoryview): - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<< - * self.dtype_is_object) - * except TypeError: - */ - __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 434, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_INCREF(__pyx_v_obj); - __Pyx_GIVEREF(__pyx_v_obj); - PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6); - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7); - __pyx_t_6 = 0; - __pyx_t_7 = 0; - __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 434, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7); - __pyx_t_7 = 0; - - /* "View.MemoryView":433 - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): - * try: # <<<<<<<<<<<<<< - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) - */ - } - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - goto __pyx_L9_try_end; - __pyx_L4_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - - /* "View.MemoryView":436 - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) - * except TypeError: # <<<<<<<<<<<<<< - * return None - * - */ - __pyx_t_9 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError); - if (__pyx_t_9) { - __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) __PYX_ERR(2, 436, __pyx_L6_except_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GOTREF(__pyx_t_8); - __Pyx_GOTREF(__pyx_t_6); - - /* "View.MemoryView":437 - * self.dtype_is_object) - * except TypeError: - * return None # <<<<<<<<<<<<<< - * - * return obj - */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - goto __pyx_L7_except_return; - } - goto __pyx_L6_except_error; - __pyx_L6_except_error:; - - /* "View.MemoryView":433 - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): - * try: # <<<<<<<<<<<<<< - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - * self.dtype_is_object) - */ - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L1_error; - __pyx_L7_except_return:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L0; - __pyx_L9_try_end:; - } - - /* "View.MemoryView":432 - * - * cdef is_slice(self, obj): - * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<< - * try: - * obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS, - */ - } - - /* "View.MemoryView":439 - * return None - * - * return obj # <<<<<<<<<<<<<< - * - * cdef setitem_slice_assignment(self, dst, src): - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_obj); - __pyx_r = __pyx_v_obj; - goto __pyx_L0; - - /* "View.MemoryView":431 - * self.setitem_indexed(index, value) - * - * cdef is_slice(self, obj): # <<<<<<<<<<<<<< - * if not isinstance(obj, memoryview): - * try: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_obj); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":441 - * return obj - * - * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice dst_slice - * cdef __Pyx_memviewslice src_slice - */ - -static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) { - __Pyx_memviewslice __pyx_v_dst_slice; - __Pyx_memviewslice __pyx_v_src_slice; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice *__pyx_t_1; - __Pyx_memviewslice *__pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("setitem_slice_assignment", 0); - - /* "View.MemoryView":445 - * cdef __Pyx_memviewslice src_slice - * - * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<< - * get_slice_from_memview(dst, &dst_slice)[0], - * src.ndim, dst.ndim, self.dtype_is_object) - */ - if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) __PYX_ERR(2, 445, __pyx_L1_error) - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(2, 445, __pyx_L1_error) - - /* "View.MemoryView":446 - * - * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], - * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<< - * src.ndim, dst.ndim, self.dtype_is_object) - * - */ - if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) __PYX_ERR(2, 446, __pyx_L1_error) - __pyx_t_2 = __pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice)); if (unlikely(__pyx_t_2 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(2, 446, __pyx_L1_error) - - /* "View.MemoryView":447 - * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], - * get_slice_from_memview(dst, &dst_slice)[0], - * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<< - * - * cdef setitem_slice_assign_scalar(self, memoryview dst, value): - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 447, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 447, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 447, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 447, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "View.MemoryView":445 - * cdef __Pyx_memviewslice src_slice - * - * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<< - * get_slice_from_memview(dst, &dst_slice)[0], - * src.ndim, dst.ndim, self.dtype_is_object) - */ - __pyx_t_6 = __pyx_memoryview_copy_contents((__pyx_t_1[0]), (__pyx_t_2[0]), __pyx_t_4, __pyx_t_5, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(2, 445, __pyx_L1_error) - - /* "View.MemoryView":441 - * return obj - * - * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice dst_slice - * cdef __Pyx_memviewslice src_slice - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":449 - * src.ndim, dst.ndim, self.dtype_is_object) - * - * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<< - * cdef int array[128] - * cdef void *tmp = NULL - */ - -static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) { - int __pyx_v_array[0x80]; - void *__pyx_v_tmp; - void *__pyx_v_item; - __Pyx_memviewslice *__pyx_v_dst_slice; - __Pyx_memviewslice __pyx_v_tmp_slice; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice *__pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - int __pyx_t_5; - char const *__pyx_t_6; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; - PyObject *__pyx_t_11 = NULL; - PyObject *__pyx_t_12 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0); - - /* "View.MemoryView":451 - * cdef setitem_slice_assign_scalar(self, memoryview dst, value): - * cdef int array[128] - * cdef void *tmp = NULL # <<<<<<<<<<<<<< - * cdef void *item - * - */ - __pyx_v_tmp = NULL; - - /* "View.MemoryView":456 - * cdef __Pyx_memviewslice *dst_slice - * cdef __Pyx_memviewslice tmp_slice - * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<< - * - * if self.view.itemsize > sizeof(array): - */ - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(2, 456, __pyx_L1_error) - __pyx_v_dst_slice = __pyx_t_1; - - /* "View.MemoryView":458 - * dst_slice = get_slice_from_memview(dst, &tmp_slice) - * - * if self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<< - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: - */ - __pyx_t_2 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":459 - * - * if self.view.itemsize > sizeof(array): - * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<< - * if tmp == NULL: - * raise MemoryError - */ - __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize); - - /* "View.MemoryView":460 - * if self.view.itemsize > sizeof(array): - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: # <<<<<<<<<<<<<< - * raise MemoryError - * item = tmp - */ - __pyx_t_2 = ((__pyx_v_tmp == NULL) != 0); - if (unlikely(__pyx_t_2)) { - - /* "View.MemoryView":461 - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: - * raise MemoryError # <<<<<<<<<<<<<< - * item = tmp - * else: - */ - PyErr_NoMemory(); __PYX_ERR(2, 461, __pyx_L1_error) - - /* "View.MemoryView":460 - * if self.view.itemsize > sizeof(array): - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: # <<<<<<<<<<<<<< - * raise MemoryError - * item = tmp - */ - } - - /* "View.MemoryView":462 - * if tmp == NULL: - * raise MemoryError - * item = tmp # <<<<<<<<<<<<<< - * else: - * item = array - */ - __pyx_v_item = __pyx_v_tmp; - - /* "View.MemoryView":458 - * dst_slice = get_slice_from_memview(dst, &tmp_slice) - * - * if self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<< - * tmp = PyMem_Malloc(self.view.itemsize) - * if tmp == NULL: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":464 - * item = tmp - * else: - * item = array # <<<<<<<<<<<<<< - * - * try: - */ - /*else*/ { - __pyx_v_item = ((void *)__pyx_v_array); - } - __pyx_L3:; - - /* "View.MemoryView":466 - * item = array - * - * try: # <<<<<<<<<<<<<< - * if self.dtype_is_object: - * ( item)[0] = value - */ - /*try:*/ { - - /* "View.MemoryView":467 - * - * try: - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * ( item)[0] = value - * else: - */ - __pyx_t_2 = (__pyx_v_self->dtype_is_object != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":468 - * try: - * if self.dtype_is_object: - * ( item)[0] = value # <<<<<<<<<<<<<< - * else: - * self.assign_item_from_object( item, value) - */ - (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value); - - /* "View.MemoryView":467 - * - * try: - * if self.dtype_is_object: # <<<<<<<<<<<<<< - * ( item)[0] = value - * else: - */ - goto __pyx_L8; - } - - /* "View.MemoryView":470 - * ( item)[0] = value - * else: - * self.assign_item_from_object( item, value) # <<<<<<<<<<<<<< - * - * - */ - /*else*/ { - __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 470, __pyx_L6_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - __pyx_L8:; - - /* "View.MemoryView":474 - * - * - * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<< - * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) - * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, - */ - __pyx_t_2 = ((__pyx_v_self->view.suboffsets != NULL) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":475 - * - * if self.view.suboffsets != NULL: - * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<< - * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, - * item, self.dtype_is_object) - */ - __pyx_t_3 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 475, __pyx_L6_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "View.MemoryView":474 - * - * - * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<< - * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) - * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, - */ - } - - /* "View.MemoryView":476 - * if self.view.suboffsets != NULL: - * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) - * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<< - * item, self.dtype_is_object) - * finally: - */ - __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object); - } - - /* "View.MemoryView":479 - * item, self.dtype_is_object) - * finally: - * PyMem_Free(tmp) # <<<<<<<<<<<<<< - * - * cdef setitem_indexed(self, index, value): - */ - /*finally:*/ { - /*normal exit:*/{ - PyMem_Free(__pyx_v_tmp); - goto __pyx_L7; - } - __pyx_L6_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_10, &__pyx_t_11, &__pyx_t_12); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9) < 0)) __Pyx_ErrFetch(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - __Pyx_XGOTREF(__pyx_t_9); - __Pyx_XGOTREF(__pyx_t_10); - __Pyx_XGOTREF(__pyx_t_11); - __Pyx_XGOTREF(__pyx_t_12); - __pyx_t_4 = __pyx_lineno; __pyx_t_5 = __pyx_clineno; __pyx_t_6 = __pyx_filename; - { - PyMem_Free(__pyx_v_tmp); - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_10); - __Pyx_XGIVEREF(__pyx_t_11); - __Pyx_XGIVEREF(__pyx_t_12); - __Pyx_ExceptionReset(__pyx_t_10, __pyx_t_11, __pyx_t_12); - } - __Pyx_XGIVEREF(__pyx_t_7); - __Pyx_XGIVEREF(__pyx_t_8); - __Pyx_XGIVEREF(__pyx_t_9); - __Pyx_ErrRestore(__pyx_t_7, __pyx_t_8, __pyx_t_9); - __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; - __pyx_lineno = __pyx_t_4; __pyx_clineno = __pyx_t_5; __pyx_filename = __pyx_t_6; - goto __pyx_L1_error; - } - __pyx_L7:; - } - - /* "View.MemoryView":449 - * src.ndim, dst.ndim, self.dtype_is_object) - * - * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<< - * cdef int array[128] - * cdef void *tmp = NULL - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":481 - * PyMem_Free(tmp) - * - * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<< - * cdef char *itemp = self.get_item_pointer(index) - * self.assign_item_from_object(itemp, value) - */ - -static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { - char *__pyx_v_itemp; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - char *__pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("setitem_indexed", 0); - - /* "View.MemoryView":482 - * - * cdef setitem_indexed(self, index, value): - * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<< - * self.assign_item_from_object(itemp, value) - * - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == ((char *)NULL))) __PYX_ERR(2, 482, __pyx_L1_error) - __pyx_v_itemp = __pyx_t_1; - - /* "View.MemoryView":483 - * cdef setitem_indexed(self, index, value): - * cdef char *itemp = self.get_item_pointer(index) - * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<< - * - * cdef convert_item_to_object(self, char *itemp): - */ - __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 483, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "View.MemoryView":481 - * PyMem_Free(tmp) - * - * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<< - * cdef char *itemp = self.get_item_pointer(index) - * self.assign_item_from_object(itemp, value) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":485 - * self.assign_item_from_object(itemp, value) - * - * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - */ - -static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) { - PyObject *__pyx_v_struct = NULL; - PyObject *__pyx_v_bytesitem = 0; - PyObject *__pyx_v_result = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - PyObject *__pyx_t_9 = NULL; - size_t __pyx_t_10; - int __pyx_t_11; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("convert_item_to_object", 0); - - /* "View.MemoryView":488 - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - * import struct # <<<<<<<<<<<<<< - * cdef bytes bytesitem - * - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 488, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_struct = __pyx_t_1; - __pyx_t_1 = 0; - - /* "View.MemoryView":491 - * cdef bytes bytesitem - * - * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<< - * try: - * result = struct.unpack(self.view.format, bytesitem) - */ - __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 491, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_bytesitem = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "View.MemoryView":492 - * - * bytesitem = itemp[:self.view.itemsize] - * try: # <<<<<<<<<<<<<< - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - - /* "View.MemoryView":493 - * bytesitem = itemp[:self.view.itemsize] - * try: - * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<< - * except struct.error: - * raise ValueError("Unable to convert item to object") - */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 493, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 493, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = NULL; - __pyx_t_8 = 0; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5); - if (likely(__pyx_t_7)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_7); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_5, function); - __pyx_t_8 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_5)) { - PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_t_6, __pyx_v_bytesitem}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 493, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) { - PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_t_6, __pyx_v_bytesitem}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 493, __pyx_L3_error) - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } else - #endif - { - __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 493, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_9); - if (__pyx_t_7) { - __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL; - } - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6); - __Pyx_INCREF(__pyx_v_bytesitem); - __Pyx_GIVEREF(__pyx_v_bytesitem); - PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem); - __pyx_t_6 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 493, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_v_result = __pyx_t_1; - __pyx_t_1 = 0; - - /* "View.MemoryView":492 - * - * bytesitem = itemp[:self.view.itemsize] - * try: # <<<<<<<<<<<<<< - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: - */ - } - - /* "View.MemoryView":497 - * raise ValueError("Unable to convert item to object") - * else: - * if len(self.view.format) == 1: # <<<<<<<<<<<<<< - * return result[0] - * return result - */ - /*else:*/ { - __pyx_t_10 = strlen(__pyx_v_self->view.format); - __pyx_t_11 = ((__pyx_t_10 == 1) != 0); - if (__pyx_t_11) { - - /* "View.MemoryView":498 - * else: - * if len(self.view.format) == 1: - * return result[0] # <<<<<<<<<<<<<< - * return result - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 498, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L6_except_return; - - /* "View.MemoryView":497 - * raise ValueError("Unable to convert item to object") - * else: - * if len(self.view.format) == 1: # <<<<<<<<<<<<<< - * return result[0] - * return result - */ - } - - /* "View.MemoryView":499 - * if len(self.view.format) == 1: - * return result[0] - * return result # <<<<<<<<<<<<<< - * - * cdef assign_item_from_object(self, char *itemp, object value): - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_result); - __pyx_r = __pyx_v_result; - goto __pyx_L6_except_return; - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "View.MemoryView":494 - * try: - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: # <<<<<<<<<<<<<< - * raise ValueError("Unable to convert item to object") - * else: - */ - __Pyx_ErrFetch(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9); - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 494, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_8 = __Pyx_PyErr_GivenExceptionMatches(__pyx_t_1, __pyx_t_6); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_ErrRestore(__pyx_t_1, __pyx_t_5, __pyx_t_9); - __pyx_t_1 = 0; __pyx_t_5 = 0; __pyx_t_9 = 0; - if (__pyx_t_8) { - __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_9, &__pyx_t_5, &__pyx_t_1) < 0) __PYX_ERR(2, 494, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_1); - - /* "View.MemoryView":495 - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: - * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<< - * else: - * if len(self.view.format) == 1: - */ - __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 495, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_Raise(__pyx_t_6, 0, 0, 0); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __PYX_ERR(2, 495, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "View.MemoryView":492 - * - * bytesitem = itemp[:self.view.itemsize] - * try: # <<<<<<<<<<<<<< - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: - */ - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L6_except_return:; - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L0; - } - - /* "View.MemoryView":485 - * self.assign_item_from_object(itemp, value) - * - * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_struct); - __Pyx_XDECREF(__pyx_v_bytesitem); - __Pyx_XDECREF(__pyx_v_result); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":501 - * return result - * - * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - */ - -static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) { - PyObject *__pyx_v_struct = NULL; - char __pyx_v_c; - PyObject *__pyx_v_bytesvalue = 0; - Py_ssize_t __pyx_v_i; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - int __pyx_t_7; - PyObject *__pyx_t_8 = NULL; - Py_ssize_t __pyx_t_9; - PyObject *__pyx_t_10 = NULL; - char *__pyx_t_11; - char *__pyx_t_12; - char *__pyx_t_13; - char *__pyx_t_14; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("assign_item_from_object", 0); - - /* "View.MemoryView":504 - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - * import struct # <<<<<<<<<<<<<< - * cdef char c - * cdef bytes bytesvalue - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 504, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_struct = __pyx_t_1; - __pyx_t_1 = 0; - - /* "View.MemoryView":509 - * cdef Py_ssize_t i - * - * if isinstance(value, tuple): # <<<<<<<<<<<<<< - * bytesvalue = struct.pack(self.view.format, *value) - * else: - */ - __pyx_t_2 = PyTuple_Check(__pyx_v_value); - __pyx_t_3 = (__pyx_t_2 != 0); - if (__pyx_t_3) { - - /* "View.MemoryView":510 - * - * if isinstance(value, tuple): - * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<< - * else: - * bytesvalue = struct.pack(self.view.format, value) - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 510, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 510, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 510, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); - __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 510, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 510, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 510, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) __PYX_ERR(2, 510, __pyx_L1_error) - __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4); - __pyx_t_4 = 0; - - /* "View.MemoryView":509 - * cdef Py_ssize_t i - * - * if isinstance(value, tuple): # <<<<<<<<<<<<<< - * bytesvalue = struct.pack(self.view.format, *value) - * else: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":512 - * bytesvalue = struct.pack(self.view.format, *value) - * else: - * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<< - * - * for i, c in enumerate(bytesvalue): - */ - /*else*/ { - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 512, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 512, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = NULL; - __pyx_t_7 = 0; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_6, function); - __pyx_t_7 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_6)) { - PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_1, __pyx_v_value}; - __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 512, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) { - PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_1, __pyx_v_value}; - __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 512, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - } else - #endif - { - __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 512, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - if (__pyx_t_5) { - __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __pyx_t_5 = NULL; - } - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1); - __Pyx_INCREF(__pyx_v_value); - __Pyx_GIVEREF(__pyx_v_value); - PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value); - __pyx_t_1 = 0; - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 512, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - } - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) __PYX_ERR(2, 512, __pyx_L1_error) - __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4); - __pyx_t_4 = 0; - } - __pyx_L3:; - - /* "View.MemoryView":514 - * bytesvalue = struct.pack(self.view.format, value) - * - * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<< - * itemp[i] = c - * - */ - __pyx_t_9 = 0; - if (unlikely(__pyx_v_bytesvalue == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable"); - __PYX_ERR(2, 514, __pyx_L1_error) - } - __Pyx_INCREF(__pyx_v_bytesvalue); - __pyx_t_10 = __pyx_v_bytesvalue; - __pyx_t_12 = PyBytes_AS_STRING(__pyx_t_10); - __pyx_t_13 = (__pyx_t_12 + PyBytes_GET_SIZE(__pyx_t_10)); - for (__pyx_t_14 = __pyx_t_12; __pyx_t_14 < __pyx_t_13; __pyx_t_14++) { - __pyx_t_11 = __pyx_t_14; - __pyx_v_c = (__pyx_t_11[0]); - - /* "View.MemoryView":515 - * - * for i, c in enumerate(bytesvalue): - * itemp[i] = c # <<<<<<<<<<<<<< - * - * @cname('getbuffer') - */ - __pyx_v_i = __pyx_t_9; - - /* "View.MemoryView":514 - * bytesvalue = struct.pack(self.view.format, value) - * - * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<< - * itemp[i] = c - * - */ - __pyx_t_9 = (__pyx_t_9 + 1); - - /* "View.MemoryView":515 - * - * for i, c in enumerate(bytesvalue): - * itemp[i] = c # <<<<<<<<<<<<<< - * - * @cname('getbuffer') - */ - (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c; - } - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - - /* "View.MemoryView":501 - * return result - * - * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< - * """Only used if instantiated manually by the user, or if Cython doesn't - * know how to convert the type""" - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_struct); - __Pyx_XDECREF(__pyx_v_bytesvalue); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":518 - * - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<< - * if flags & PyBUF_WRITABLE and self.view.readonly: - * raise ValueError("Cannot create writable memory view from read-only memoryview") - */ - -/* Python wrapper */ -static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ -static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - Py_ssize_t *__pyx_t_4; - char *__pyx_t_5; - void *__pyx_t_6; - int __pyx_t_7; - Py_ssize_t __pyx_t_8; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - if (__pyx_v_info == NULL) { - PyErr_SetString(PyExc_BufferError, "PyObject_GetBuffer: view==NULL argument is obsolete"); - return -1; - } - __Pyx_RefNannySetupContext("__getbuffer__", 0); - __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(__pyx_v_info->obj); - - /* "View.MemoryView":519 - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: # <<<<<<<<<<<<<< - * raise ValueError("Cannot create writable memory view from read-only memoryview") - * - */ - __pyx_t_2 = ((__pyx_v_flags & PyBUF_WRITABLE) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_2 = (__pyx_v_self->view.readonly != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L4_bool_binop_done:; - if (unlikely(__pyx_t_1)) { - - /* "View.MemoryView":520 - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: - * raise ValueError("Cannot create writable memory view from read-only memoryview") # <<<<<<<<<<<<<< - * - * if flags & PyBUF_ND: - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 520, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 520, __pyx_L1_error) - - /* "View.MemoryView":519 - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: # <<<<<<<<<<<<<< - * raise ValueError("Cannot create writable memory view from read-only memoryview") - * - */ - } - - /* "View.MemoryView":522 - * raise ValueError("Cannot create writable memory view from read-only memoryview") - * - * if flags & PyBUF_ND: # <<<<<<<<<<<<<< - * info.shape = self.view.shape - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_ND) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":523 - * - * if flags & PyBUF_ND: - * info.shape = self.view.shape # <<<<<<<<<<<<<< - * else: - * info.shape = NULL - */ - __pyx_t_4 = __pyx_v_self->view.shape; - __pyx_v_info->shape = __pyx_t_4; - - /* "View.MemoryView":522 - * raise ValueError("Cannot create writable memory view from read-only memoryview") - * - * if flags & PyBUF_ND: # <<<<<<<<<<<<<< - * info.shape = self.view.shape - * else: - */ - goto __pyx_L6; - } - - /* "View.MemoryView":525 - * info.shape = self.view.shape - * else: - * info.shape = NULL # <<<<<<<<<<<<<< - * - * if flags & PyBUF_STRIDES: - */ - /*else*/ { - __pyx_v_info->shape = NULL; - } - __pyx_L6:; - - /* "View.MemoryView":527 - * info.shape = NULL - * - * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< - * info.strides = self.view.strides - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":528 - * - * if flags & PyBUF_STRIDES: - * info.strides = self.view.strides # <<<<<<<<<<<<<< - * else: - * info.strides = NULL - */ - __pyx_t_4 = __pyx_v_self->view.strides; - __pyx_v_info->strides = __pyx_t_4; - - /* "View.MemoryView":527 - * info.shape = NULL - * - * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< - * info.strides = self.view.strides - * else: - */ - goto __pyx_L7; - } - - /* "View.MemoryView":530 - * info.strides = self.view.strides - * else: - * info.strides = NULL # <<<<<<<<<<<<<< - * - * if flags & PyBUF_INDIRECT: - */ - /*else*/ { - __pyx_v_info->strides = NULL; - } - __pyx_L7:; - - /* "View.MemoryView":532 - * info.strides = NULL - * - * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<< - * info.suboffsets = self.view.suboffsets - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":533 - * - * if flags & PyBUF_INDIRECT: - * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<< - * else: - * info.suboffsets = NULL - */ - __pyx_t_4 = __pyx_v_self->view.suboffsets; - __pyx_v_info->suboffsets = __pyx_t_4; - - /* "View.MemoryView":532 - * info.strides = NULL - * - * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<< - * info.suboffsets = self.view.suboffsets - * else: - */ - goto __pyx_L8; - } - - /* "View.MemoryView":535 - * info.suboffsets = self.view.suboffsets - * else: - * info.suboffsets = NULL # <<<<<<<<<<<<<< - * - * if flags & PyBUF_FORMAT: - */ - /*else*/ { - __pyx_v_info->suboffsets = NULL; - } - __pyx_L8:; - - /* "View.MemoryView":537 - * info.suboffsets = NULL - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * info.format = self.view.format - * else: - */ - __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":538 - * - * if flags & PyBUF_FORMAT: - * info.format = self.view.format # <<<<<<<<<<<<<< - * else: - * info.format = NULL - */ - __pyx_t_5 = __pyx_v_self->view.format; - __pyx_v_info->format = __pyx_t_5; - - /* "View.MemoryView":537 - * info.suboffsets = NULL - * - * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< - * info.format = self.view.format - * else: - */ - goto __pyx_L9; - } - - /* "View.MemoryView":540 - * info.format = self.view.format - * else: - * info.format = NULL # <<<<<<<<<<<<<< - * - * info.buf = self.view.buf - */ - /*else*/ { - __pyx_v_info->format = NULL; - } - __pyx_L9:; - - /* "View.MemoryView":542 - * info.format = NULL - * - * info.buf = self.view.buf # <<<<<<<<<<<<<< - * info.ndim = self.view.ndim - * info.itemsize = self.view.itemsize - */ - __pyx_t_6 = __pyx_v_self->view.buf; - __pyx_v_info->buf = __pyx_t_6; - - /* "View.MemoryView":543 - * - * info.buf = self.view.buf - * info.ndim = self.view.ndim # <<<<<<<<<<<<<< - * info.itemsize = self.view.itemsize - * info.len = self.view.len - */ - __pyx_t_7 = __pyx_v_self->view.ndim; - __pyx_v_info->ndim = __pyx_t_7; - - /* "View.MemoryView":544 - * info.buf = self.view.buf - * info.ndim = self.view.ndim - * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<< - * info.len = self.view.len - * info.readonly = self.view.readonly - */ - __pyx_t_8 = __pyx_v_self->view.itemsize; - __pyx_v_info->itemsize = __pyx_t_8; - - /* "View.MemoryView":545 - * info.ndim = self.view.ndim - * info.itemsize = self.view.itemsize - * info.len = self.view.len # <<<<<<<<<<<<<< - * info.readonly = self.view.readonly - * info.obj = self - */ - __pyx_t_8 = __pyx_v_self->view.len; - __pyx_v_info->len = __pyx_t_8; - - /* "View.MemoryView":546 - * info.itemsize = self.view.itemsize - * info.len = self.view.len - * info.readonly = self.view.readonly # <<<<<<<<<<<<<< - * info.obj = self - * - */ - __pyx_t_1 = __pyx_v_self->view.readonly; - __pyx_v_info->readonly = __pyx_t_1; - - /* "View.MemoryView":547 - * info.len = self.view.len - * info.readonly = self.view.readonly - * info.obj = self # <<<<<<<<<<<<<< - * - * __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") - */ - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); - __pyx_v_info->obj = ((PyObject *)__pyx_v_self); - - /* "View.MemoryView":518 - * - * @cname('getbuffer') - * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<< - * if flags & PyBUF_WRITABLE and self.view.readonly: - * raise ValueError("Cannot create writable memory view from read-only memoryview") - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - if (__pyx_v_info->obj != NULL) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - goto __pyx_L2; - __pyx_L0:; - if (__pyx_v_info->obj == Py_None) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = 0; - } - __pyx_L2:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":553 - * - * @property - * def T(self): # <<<<<<<<<<<<<< - * cdef _memoryviewslice result = memoryview_copy(self) - * transpose_memslice(&result.from_slice) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - struct __pyx_memoryviewslice_obj *__pyx_v_result = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "View.MemoryView":554 - * @property - * def T(self): - * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<< - * transpose_memslice(&result.from_slice) - * return result - */ - __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 554, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) __PYX_ERR(2, 554, __pyx_L1_error) - __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1); - __pyx_t_1 = 0; - - /* "View.MemoryView":555 - * def T(self): - * cdef _memoryviewslice result = memoryview_copy(self) - * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<< - * return result - * - */ - __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(2, 555, __pyx_L1_error) - - /* "View.MemoryView":556 - * cdef _memoryviewslice result = memoryview_copy(self) - * transpose_memslice(&result.from_slice) - * return result # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_result)); - __pyx_r = ((PyObject *)__pyx_v_result); - goto __pyx_L0; - - /* "View.MemoryView":553 - * - * @property - * def T(self): # <<<<<<<<<<<<<< - * cdef _memoryviewslice result = memoryview_copy(self) - * transpose_memslice(&result.from_slice) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_result); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":559 - * - * @property - * def base(self): # <<<<<<<<<<<<<< - * return self.obj - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - - /* "View.MemoryView":560 - * @property - * def base(self): - * return self.obj # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->obj); - __pyx_r = __pyx_v_self->obj; - goto __pyx_L0; - - /* "View.MemoryView":559 - * - * @property - * def base(self): # <<<<<<<<<<<<<< - * return self.obj - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":563 - * - * @property - * def shape(self): # <<<<<<<<<<<<<< - * return tuple([length for length in self.view.shape[:self.view.ndim]]) - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - Py_ssize_t __pyx_v_length; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t *__pyx_t_2; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "View.MemoryView":564 - * @property - * def shape(self): - * return tuple([length for length in self.view.shape[:self.view.ndim]]) # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 564, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = (__pyx_v_self->view.shape + __pyx_v_self->view.ndim); - for (__pyx_t_4 = __pyx_v_self->view.shape; __pyx_t_4 < __pyx_t_3; __pyx_t_4++) { - __pyx_t_2 = __pyx_t_4; - __pyx_v_length = (__pyx_t_2[0]); - __pyx_t_5 = PyInt_FromSsize_t(__pyx_v_length); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 564, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_5))) __PYX_ERR(2, 564, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } - __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 564, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; - goto __pyx_L0; - - /* "View.MemoryView":563 - * - * @property - * def shape(self): # <<<<<<<<<<<<<< - * return tuple([length for length in self.view.shape[:self.view.ndim]]) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":567 - * - * @property - * def strides(self): # <<<<<<<<<<<<<< - * if self.view.strides == NULL: - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - Py_ssize_t __pyx_v_stride; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; - Py_ssize_t *__pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "View.MemoryView":568 - * @property - * def strides(self): - * if self.view.strides == NULL: # <<<<<<<<<<<<<< - * - * raise ValueError("Buffer view does not expose strides") - */ - __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0); - if (unlikely(__pyx_t_1)) { - - /* "View.MemoryView":570 - * if self.view.strides == NULL: - * - * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<< - * - * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) - */ - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 570, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(2, 570, __pyx_L1_error) - - /* "View.MemoryView":568 - * @property - * def strides(self): - * if self.view.strides == NULL: # <<<<<<<<<<<<<< - * - * raise ValueError("Buffer view does not expose strides") - */ - } - - /* "View.MemoryView":572 - * raise ValueError("Buffer view does not expose strides") - * - * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 572, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = (__pyx_v_self->view.strides + __pyx_v_self->view.ndim); - for (__pyx_t_5 = __pyx_v_self->view.strides; __pyx_t_5 < __pyx_t_4; __pyx_t_5++) { - __pyx_t_3 = __pyx_t_5; - __pyx_v_stride = (__pyx_t_3[0]); - __pyx_t_6 = PyInt_FromSsize_t(__pyx_v_stride); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 572, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_6))) __PYX_ERR(2, 572, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - } - __pyx_t_6 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 572, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_6; - __pyx_t_6 = 0; - goto __pyx_L0; - - /* "View.MemoryView":567 - * - * @property - * def strides(self): # <<<<<<<<<<<<<< - * if self.view.strides == NULL: - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":575 - * - * @property - * def suboffsets(self): # <<<<<<<<<<<<<< - * if self.view.suboffsets == NULL: - * return (-1,) * self.view.ndim - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - Py_ssize_t __pyx_v_suboffset; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - Py_ssize_t *__pyx_t_4; - Py_ssize_t *__pyx_t_5; - Py_ssize_t *__pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "View.MemoryView":576 - * @property - * def suboffsets(self): - * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<< - * return (-1,) * self.view.ndim - * - */ - __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":577 - * def suboffsets(self): - * if self.view.suboffsets == NULL: - * return (-1,) * self.view.ndim # <<<<<<<<<<<<<< - * - * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 577, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyNumber_Multiply(__pyx_tuple__19, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 577, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "View.MemoryView":576 - * @property - * def suboffsets(self): - * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<< - * return (-1,) * self.view.ndim - * - */ - } - - /* "View.MemoryView":579 - * return (-1,) * self.view.ndim - * - * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 579, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = (__pyx_v_self->view.suboffsets + __pyx_v_self->view.ndim); - for (__pyx_t_6 = __pyx_v_self->view.suboffsets; __pyx_t_6 < __pyx_t_5; __pyx_t_6++) { - __pyx_t_4 = __pyx_t_6; - __pyx_v_suboffset = (__pyx_t_4[0]); - __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_suboffset); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 579, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_2))) __PYX_ERR(2, 579, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - } - __pyx_t_2 = PyList_AsTuple(((PyObject*)__pyx_t_3)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 579, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":575 - * - * @property - * def suboffsets(self): # <<<<<<<<<<<<<< - * if self.view.suboffsets == NULL: - * return (-1,) * self.view.ndim - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":582 - * - * @property - * def ndim(self): # <<<<<<<<<<<<<< - * return self.view.ndim - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "View.MemoryView":583 - * @property - * def ndim(self): - * return self.view.ndim # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 583, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "View.MemoryView":582 - * - * @property - * def ndim(self): # <<<<<<<<<<<<<< - * return self.view.ndim - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":586 - * - * @property - * def itemsize(self): # <<<<<<<<<<<<<< - * return self.view.itemsize - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "View.MemoryView":587 - * @property - * def itemsize(self): - * return self.view.itemsize # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 587, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "View.MemoryView":586 - * - * @property - * def itemsize(self): # <<<<<<<<<<<<<< - * return self.view.itemsize - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":590 - * - * @property - * def nbytes(self): # <<<<<<<<<<<<<< - * return self.size * self.view.itemsize - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "View.MemoryView":591 - * @property - * def nbytes(self): - * return self.size * self.view.itemsize # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 591, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 591, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 591, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "View.MemoryView":590 - * - * @property - * def nbytes(self): # <<<<<<<<<<<<<< - * return self.size * self.view.itemsize - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":594 - * - * @property - * def size(self): # <<<<<<<<<<<<<< - * if self._size is None: - * result = 1 - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_v_result = NULL; - PyObject *__pyx_v_length = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; - Py_ssize_t *__pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "View.MemoryView":595 - * @property - * def size(self): - * if self._size is None: # <<<<<<<<<<<<<< - * result = 1 - * - */ - __pyx_t_1 = (__pyx_v_self->_size == Py_None); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":596 - * def size(self): - * if self._size is None: - * result = 1 # <<<<<<<<<<<<<< - * - * for length in self.view.shape[:self.view.ndim]: - */ - __Pyx_INCREF(__pyx_int_1); - __pyx_v_result = __pyx_int_1; - - /* "View.MemoryView":598 - * result = 1 - * - * for length in self.view.shape[:self.view.ndim]: # <<<<<<<<<<<<<< - * result *= length - * - */ - __pyx_t_4 = (__pyx_v_self->view.shape + __pyx_v_self->view.ndim); - for (__pyx_t_5 = __pyx_v_self->view.shape; __pyx_t_5 < __pyx_t_4; __pyx_t_5++) { - __pyx_t_3 = __pyx_t_5; - __pyx_t_6 = PyInt_FromSsize_t((__pyx_t_3[0])); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 598, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_6); - __pyx_t_6 = 0; - - /* "View.MemoryView":599 - * - * for length in self.view.shape[:self.view.ndim]: - * result *= length # <<<<<<<<<<<<<< - * - * self._size = result - */ - __pyx_t_6 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 599, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_6); - __pyx_t_6 = 0; - } - - /* "View.MemoryView":601 - * result *= length - * - * self._size = result # <<<<<<<<<<<<<< - * - * return self._size - */ - __Pyx_INCREF(__pyx_v_result); - __Pyx_GIVEREF(__pyx_v_result); - __Pyx_GOTREF(__pyx_v_self->_size); - __Pyx_DECREF(__pyx_v_self->_size); - __pyx_v_self->_size = __pyx_v_result; - - /* "View.MemoryView":595 - * @property - * def size(self): - * if self._size is None: # <<<<<<<<<<<<<< - * result = 1 - * - */ - } - - /* "View.MemoryView":603 - * self._size = result - * - * return self._size # <<<<<<<<<<<<<< - * - * def __len__(self): - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->_size); - __pyx_r = __pyx_v_self->_size; - goto __pyx_L0; - - /* "View.MemoryView":594 - * - * @property - * def size(self): # <<<<<<<<<<<<<< - * if self._size is None: - * result = 1 - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_result); - __Pyx_XDECREF(__pyx_v_length); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":605 - * return self._size - * - * def __len__(self): # <<<<<<<<<<<<<< - * if self.view.ndim >= 1: - * return self.view.shape[0] - */ - -/* Python wrapper */ -static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/ -static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) { - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static Py_ssize_t __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) { - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("__len__", 0); - - /* "View.MemoryView":606 - * - * def __len__(self): - * if self.view.ndim >= 1: # <<<<<<<<<<<<<< - * return self.view.shape[0] - * - */ - __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":607 - * def __len__(self): - * if self.view.ndim >= 1: - * return self.view.shape[0] # <<<<<<<<<<<<<< - * - * return 0 - */ - __pyx_r = (__pyx_v_self->view.shape[0]); - goto __pyx_L0; - - /* "View.MemoryView":606 - * - * def __len__(self): - * if self.view.ndim >= 1: # <<<<<<<<<<<<<< - * return self.view.shape[0] - * - */ - } - - /* "View.MemoryView":609 - * return self.view.shape[0] - * - * return 0 # <<<<<<<<<<<<<< - * - * def __repr__(self): - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "View.MemoryView":605 - * return self._size - * - * def __len__(self): # <<<<<<<<<<<<<< - * if self.view.ndim >= 1: - * return self.view.shape[0] - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":611 - * return 0 - * - * def __repr__(self): # <<<<<<<<<<<<<< - * return "" % (self.base.__class__.__name__, - * id(self)) - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__repr__", 0); - - /* "View.MemoryView":612 - * - * def __repr__(self): - * return "" % (self.base.__class__.__name__, # <<<<<<<<<<<<<< - * id(self)) - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 612, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 612, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 612, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "View.MemoryView":613 - * def __repr__(self): - * return "" % (self.base.__class__.__name__, - * id(self)) # <<<<<<<<<<<<<< - * - * def __str__(self): - */ - __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 613, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - - /* "View.MemoryView":612 - * - * def __repr__(self): - * return "" % (self.base.__class__.__name__, # <<<<<<<<<<<<<< - * id(self)) - * - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 612, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 612, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":611 - * return 0 - * - * def __repr__(self): # <<<<<<<<<<<<<< - * return "" % (self.base.__class__.__name__, - * id(self)) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":615 - * id(self)) - * - * def __str__(self): # <<<<<<<<<<<<<< - * return "" % (self.base.__class__.__name__,) - * - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__str__ (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__str__", 0); - - /* "View.MemoryView":616 - * - * def __str__(self): - * return "" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 616, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 616, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 616, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 616, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 616, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "View.MemoryView":615 - * id(self)) - * - * def __str__(self): # <<<<<<<<<<<<<< - * return "" % (self.base.__class__.__name__,) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":619 - * - * - * def is_c_contig(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) { - __Pyx_memviewslice *__pyx_v_mslice; - __Pyx_memviewslice __pyx_v_tmp; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice *__pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("is_c_contig", 0); - - /* "View.MemoryView":622 - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<< - * return slice_is_contig(mslice[0], 'C', self.view.ndim) - * - */ - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(2, 622, __pyx_L1_error) - __pyx_v_mslice = __pyx_t_1; - - /* "View.MemoryView":623 - * cdef __Pyx_memviewslice tmp - * mslice = get_slice_from_memview(self, &tmp) - * return slice_is_contig(mslice[0], 'C', self.view.ndim) # <<<<<<<<<<<<<< - * - * def is_f_contig(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig((__pyx_v_mslice[0]), 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 623, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":619 - * - * - * def is_c_contig(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":625 - * return slice_is_contig(mslice[0], 'C', self.view.ndim) - * - * def is_f_contig(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) { - __Pyx_memviewslice *__pyx_v_mslice; - __Pyx_memviewslice __pyx_v_tmp; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice *__pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("is_f_contig", 0); - - /* "View.MemoryView":628 - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<< - * return slice_is_contig(mslice[0], 'F', self.view.ndim) - * - */ - __pyx_t_1 = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp)); if (unlikely(__pyx_t_1 == ((__Pyx_memviewslice *)NULL))) __PYX_ERR(2, 628, __pyx_L1_error) - __pyx_v_mslice = __pyx_t_1; - - /* "View.MemoryView":629 - * cdef __Pyx_memviewslice tmp - * mslice = get_slice_from_memview(self, &tmp) - * return slice_is_contig(mslice[0], 'F', self.view.ndim) # <<<<<<<<<<<<<< - * - * def copy(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig((__pyx_v_mslice[0]), 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 629, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":625 - * return slice_is_contig(mslice[0], 'C', self.view.ndim) - * - * def is_f_contig(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice *mslice - * cdef __Pyx_memviewslice tmp - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":631 - * return slice_is_contig(mslice[0], 'F', self.view.ndim) - * - * def copy(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice mslice - * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("copy (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) { - __Pyx_memviewslice __pyx_v_mslice; - int __pyx_v_flags; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("copy", 0); - - /* "View.MemoryView":633 - * def copy(self): - * cdef __Pyx_memviewslice mslice - * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<< - * - * slice_copy(self, &mslice) - */ - __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS)); - - /* "View.MemoryView":635 - * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS - * - * slice_copy(self, &mslice) # <<<<<<<<<<<<<< - * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, - * self.view.itemsize, - */ - __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice)); - - /* "View.MemoryView":636 - * - * slice_copy(self, &mslice) - * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<< - * self.view.itemsize, - * flags|PyBUF_C_CONTIGUOUS, - */ - __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), ((char *)"c"), __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 636, __pyx_L1_error) - __pyx_v_mslice = __pyx_t_1; - - /* "View.MemoryView":641 - * self.dtype_is_object) - * - * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<< - * - * def copy_fortran(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 641, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":631 - * return slice_is_contig(mslice[0], 'F', self.view.ndim) - * - * def copy(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice mslice - * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":643 - * return memoryview_copy_from_slice(self, &mslice) - * - * def copy_fortran(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice src, dst - * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS - */ - -/* Python wrapper */ -static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0); - __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) { - __Pyx_memviewslice __pyx_v_src; - __Pyx_memviewslice __pyx_v_dst; - int __pyx_v_flags; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_memviewslice __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("copy_fortran", 0); - - /* "View.MemoryView":645 - * def copy_fortran(self): - * cdef __Pyx_memviewslice src, dst - * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<< - * - * slice_copy(self, &src) - */ - __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS)); - - /* "View.MemoryView":647 - * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS - * - * slice_copy(self, &src) # <<<<<<<<<<<<<< - * dst = slice_copy_contig(&src, "fortran", self.view.ndim, - * self.view.itemsize, - */ - __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src)); - - /* "View.MemoryView":648 - * - * slice_copy(self, &src) - * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<< - * self.view.itemsize, - * flags|PyBUF_F_CONTIGUOUS, - */ - __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), ((char *)"fortran"), __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 648, __pyx_L1_error) - __pyx_v_dst = __pyx_t_1; - - /* "View.MemoryView":653 - * self.dtype_is_object) - * - * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 653, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":643 - * return memoryview_copy_from_slice(self, &mslice) - * - * def copy_fortran(self): # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice src, dst - * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_memoryview_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw___pyx_memoryview_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_memoryview___reduce_cython__(((struct __pyx_memoryview_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_memoryview___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_memoryview_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw___pyx_memoryview_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_memoryview_2__setstate_cython__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_memoryview_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryview_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":657 - * - * @cname('__pyx_memoryview_new') - * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<< - * cdef memoryview result = memoryview(o, flags, dtype_is_object) - * result.typeinfo = typeinfo - */ - -static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) { - struct __pyx_memoryview_obj *__pyx_v_result = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memoryview_cwrapper", 0); - - /* "View.MemoryView":658 - * @cname('__pyx_memoryview_new') - * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): - * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<< - * result.typeinfo = typeinfo - * return result - */ - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 658, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 658, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 658, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_o); - __Pyx_GIVEREF(__pyx_v_o); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 658, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2); - __pyx_t_2 = 0; - - /* "View.MemoryView":659 - * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): - * cdef memoryview result = memoryview(o, flags, dtype_is_object) - * result.typeinfo = typeinfo # <<<<<<<<<<<<<< - * return result - * - */ - __pyx_v_result->typeinfo = __pyx_v_typeinfo; - - /* "View.MemoryView":660 - * cdef memoryview result = memoryview(o, flags, dtype_is_object) - * result.typeinfo = typeinfo - * return result # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_check') - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_result)); - __pyx_r = ((PyObject *)__pyx_v_result); - goto __pyx_L0; - - /* "View.MemoryView":657 - * - * @cname('__pyx_memoryview_new') - * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<< - * cdef memoryview result = memoryview(o, flags, dtype_is_object) - * result.typeinfo = typeinfo - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_result); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":663 - * - * @cname('__pyx_memoryview_check') - * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<< - * return isinstance(o, memoryview) - * - */ - -static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("memoryview_check", 0); - - /* "View.MemoryView":664 - * @cname('__pyx_memoryview_check') - * cdef inline bint memoryview_check(object o): - * return isinstance(o, memoryview) # <<<<<<<<<<<<<< - * - * cdef tuple _unellipsify(object index, int ndim): - */ - __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, __pyx_memoryview_type); - __pyx_r = __pyx_t_1; - goto __pyx_L0; - - /* "View.MemoryView":663 - * - * @cname('__pyx_memoryview_check') - * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<< - * return isinstance(o, memoryview) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":666 - * return isinstance(o, memoryview) - * - * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<< - * """ - * Replace all ellipses with full slices and fill incomplete indices with - */ - -static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) { - PyObject *__pyx_v_tup = NULL; - PyObject *__pyx_v_result = NULL; - int __pyx_v_have_slices; - int __pyx_v_seen_ellipsis; - CYTHON_UNUSED PyObject *__pyx_v_idx = NULL; - PyObject *__pyx_v_item = NULL; - Py_ssize_t __pyx_v_nslices; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - Py_ssize_t __pyx_t_5; - PyObject *(*__pyx_t_6)(PyObject *); - PyObject *__pyx_t_7 = NULL; - Py_ssize_t __pyx_t_8; - int __pyx_t_9; - int __pyx_t_10; - PyObject *__pyx_t_11 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_unellipsify", 0); - - /* "View.MemoryView":671 - * full slices. - * """ - * if not isinstance(index, tuple): # <<<<<<<<<<<<<< - * tup = (index,) - * else: - */ - __pyx_t_1 = PyTuple_Check(__pyx_v_index); - __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":672 - * """ - * if not isinstance(index, tuple): - * tup = (index,) # <<<<<<<<<<<<<< - * else: - * tup = index - */ - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 672, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_index); - __Pyx_GIVEREF(__pyx_v_index); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index); - __pyx_v_tup = __pyx_t_3; - __pyx_t_3 = 0; - - /* "View.MemoryView":671 - * full slices. - * """ - * if not isinstance(index, tuple): # <<<<<<<<<<<<<< - * tup = (index,) - * else: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":674 - * tup = (index,) - * else: - * tup = index # <<<<<<<<<<<<<< - * - * result = [] - */ - /*else*/ { - __Pyx_INCREF(__pyx_v_index); - __pyx_v_tup = __pyx_v_index; - } - __pyx_L3:; - - /* "View.MemoryView":676 - * tup = index - * - * result = [] # <<<<<<<<<<<<<< - * have_slices = False - * seen_ellipsis = False - */ - __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 676, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_v_result = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":677 - * - * result = [] - * have_slices = False # <<<<<<<<<<<<<< - * seen_ellipsis = False - * for idx, item in enumerate(tup): - */ - __pyx_v_have_slices = 0; - - /* "View.MemoryView":678 - * result = [] - * have_slices = False - * seen_ellipsis = False # <<<<<<<<<<<<<< - * for idx, item in enumerate(tup): - * if item is Ellipsis: - */ - __pyx_v_seen_ellipsis = 0; - - /* "View.MemoryView":679 - * have_slices = False - * seen_ellipsis = False - * for idx, item in enumerate(tup): # <<<<<<<<<<<<<< - * if item is Ellipsis: - * if not seen_ellipsis: - */ - __Pyx_INCREF(__pyx_int_0); - __pyx_t_3 = __pyx_int_0; - if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) { - __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0; - __pyx_t_6 = NULL; - } else { - __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 679, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 679, __pyx_L1_error) - } - for (;;) { - if (likely(!__pyx_t_6)) { - if (likely(PyList_CheckExact(__pyx_t_4))) { - if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) __PYX_ERR(2, 679, __pyx_L1_error) - #else - __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 679, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - #endif - } else { - if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) __PYX_ERR(2, 679, __pyx_L1_error) - #else - __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 679, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - #endif - } - } else { - __pyx_t_7 = __pyx_t_6(__pyx_t_4); - if (unlikely(!__pyx_t_7)) { - PyObject* exc_type = PyErr_Occurred(); - if (exc_type) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); - else __PYX_ERR(2, 679, __pyx_L1_error) - } - break; - } - __Pyx_GOTREF(__pyx_t_7); - } - __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7); - __pyx_t_7 = 0; - __Pyx_INCREF(__pyx_t_3); - __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3); - __pyx_t_7 = __Pyx_PyInt_AddObjC(__pyx_t_3, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 679, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_3); - __pyx_t_3 = __pyx_t_7; - __pyx_t_7 = 0; - - /* "View.MemoryView":680 - * seen_ellipsis = False - * for idx, item in enumerate(tup): - * if item is Ellipsis: # <<<<<<<<<<<<<< - * if not seen_ellipsis: - * result.extend([slice(None)] * (ndim - len(tup) + 1)) - */ - __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis); - __pyx_t_1 = (__pyx_t_2 != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":681 - * for idx, item in enumerate(tup): - * if item is Ellipsis: - * if not seen_ellipsis: # <<<<<<<<<<<<<< - * result.extend([slice(None)] * (ndim - len(tup) + 1)) - * seen_ellipsis = True - */ - __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":682 - * if item is Ellipsis: - * if not seen_ellipsis: - * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<< - * seen_ellipsis = True - * else: - */ - __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == ((Py_ssize_t)-1))) __PYX_ERR(2, 682, __pyx_L1_error) - __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 682, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - { Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) { - __Pyx_INCREF(__pyx_slice__22); - __Pyx_GIVEREF(__pyx_slice__22); - PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__22); - } - } - __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(2, 682, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "View.MemoryView":683 - * if not seen_ellipsis: - * result.extend([slice(None)] * (ndim - len(tup) + 1)) - * seen_ellipsis = True # <<<<<<<<<<<<<< - * else: - * result.append(slice(None)) - */ - __pyx_v_seen_ellipsis = 1; - - /* "View.MemoryView":681 - * for idx, item in enumerate(tup): - * if item is Ellipsis: - * if not seen_ellipsis: # <<<<<<<<<<<<<< - * result.extend([slice(None)] * (ndim - len(tup) + 1)) - * seen_ellipsis = True - */ - goto __pyx_L7; - } - - /* "View.MemoryView":685 - * seen_ellipsis = True - * else: - * result.append(slice(None)) # <<<<<<<<<<<<<< - * have_slices = True - * else: - */ - /*else*/ { - __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__22); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(2, 685, __pyx_L1_error) - } - __pyx_L7:; - - /* "View.MemoryView":686 - * else: - * result.append(slice(None)) - * have_slices = True # <<<<<<<<<<<<<< - * else: - * if not isinstance(item, slice) and not PyIndex_Check(item): - */ - __pyx_v_have_slices = 1; - - /* "View.MemoryView":680 - * seen_ellipsis = False - * for idx, item in enumerate(tup): - * if item is Ellipsis: # <<<<<<<<<<<<<< - * if not seen_ellipsis: - * result.extend([slice(None)] * (ndim - len(tup) + 1)) - */ - goto __pyx_L6; - } - - /* "View.MemoryView":688 - * have_slices = True - * else: - * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<< - * raise TypeError("Cannot index with type '%s'" % type(item)) - * - */ - /*else*/ { - __pyx_t_2 = PySlice_Check(__pyx_v_item); - __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0); - if (__pyx_t_10) { - } else { - __pyx_t_1 = __pyx_t_10; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0); - __pyx_t_1 = __pyx_t_10; - __pyx_L9_bool_binop_done:; - if (unlikely(__pyx_t_1)) { - - /* "View.MemoryView":689 - * else: - * if not isinstance(item, slice) and not PyIndex_Check(item): - * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<< - * - * have_slices = have_slices or isinstance(item, slice) - */ - __pyx_t_7 = __Pyx_PyString_FormatSafe(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 689, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_7); if (unlikely(!__pyx_t_11)) __PYX_ERR(2, 689, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_Raise(__pyx_t_11, 0, 0, 0); - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - __PYX_ERR(2, 689, __pyx_L1_error) - - /* "View.MemoryView":688 - * have_slices = True - * else: - * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<< - * raise TypeError("Cannot index with type '%s'" % type(item)) - * - */ - } - - /* "View.MemoryView":691 - * raise TypeError("Cannot index with type '%s'" % type(item)) - * - * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<< - * result.append(item) - * - */ - __pyx_t_10 = (__pyx_v_have_slices != 0); - if (!__pyx_t_10) { - } else { - __pyx_t_1 = __pyx_t_10; - goto __pyx_L11_bool_binop_done; - } - __pyx_t_10 = PySlice_Check(__pyx_v_item); - __pyx_t_2 = (__pyx_t_10 != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L11_bool_binop_done:; - __pyx_v_have_slices = __pyx_t_1; - - /* "View.MemoryView":692 - * - * have_slices = have_slices or isinstance(item, slice) - * result.append(item) # <<<<<<<<<<<<<< - * - * nslices = ndim - len(result) - */ - __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(2, 692, __pyx_L1_error) - } - __pyx_L6:; - - /* "View.MemoryView":679 - * have_slices = False - * seen_ellipsis = False - * for idx, item in enumerate(tup): # <<<<<<<<<<<<<< - * if item is Ellipsis: - * if not seen_ellipsis: - */ - } - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "View.MemoryView":694 - * result.append(item) - * - * nslices = ndim - len(result) # <<<<<<<<<<<<<< - * if nslices: - * result.extend([slice(None)] * nslices) - */ - __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == ((Py_ssize_t)-1))) __PYX_ERR(2, 694, __pyx_L1_error) - __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5); - - /* "View.MemoryView":695 - * - * nslices = ndim - len(result) - * if nslices: # <<<<<<<<<<<<<< - * result.extend([slice(None)] * nslices) - * - */ - __pyx_t_1 = (__pyx_v_nslices != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":696 - * nslices = ndim - len(result) - * if nslices: - * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<< - * - * return have_slices or nslices, tuple(result) - */ - __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 696, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - { Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) { - __Pyx_INCREF(__pyx_slice__22); - __Pyx_GIVEREF(__pyx_slice__22); - PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__22); - } - } - __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(2, 696, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "View.MemoryView":695 - * - * nslices = ndim - len(result) - * if nslices: # <<<<<<<<<<<<<< - * result.extend([slice(None)] * nslices) - * - */ - } - - /* "View.MemoryView":698 - * result.extend([slice(None)] * nslices) - * - * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<< - * - * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): - */ - __Pyx_XDECREF(__pyx_r); - if (!__pyx_v_have_slices) { - } else { - __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 698, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = __pyx_t_4; - __pyx_t_4 = 0; - goto __pyx_L14_bool_binop_done; - } - __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 698, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = __pyx_t_4; - __pyx_t_4 = 0; - __pyx_L14_bool_binop_done:; - __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 698, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) __PYX_ERR(2, 698, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_4); - __pyx_t_3 = 0; - __pyx_t_4 = 0; - __pyx_r = ((PyObject*)__pyx_t_11); - __pyx_t_11 = 0; - goto __pyx_L0; - - /* "View.MemoryView":666 - * return isinstance(o, memoryview) - * - * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<< - * """ - * Replace all ellipses with full slices and fill incomplete indices with - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_11); - __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_tup); - __Pyx_XDECREF(__pyx_v_result); - __Pyx_XDECREF(__pyx_v_idx); - __Pyx_XDECREF(__pyx_v_item); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":700 - * return have_slices or nslices, tuple(result) - * - * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<< - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: - */ - -static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) { - Py_ssize_t __pyx_v_suboffset; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - Py_ssize_t *__pyx_t_1; - Py_ssize_t *__pyx_t_2; - Py_ssize_t *__pyx_t_3; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("assert_direct_dimensions", 0); - - /* "View.MemoryView":701 - * - * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): - * for suboffset in suboffsets[:ndim]: # <<<<<<<<<<<<<< - * if suboffset >= 0: - * raise ValueError("Indirect dimensions not supported") - */ - __pyx_t_2 = (__pyx_v_suboffsets + __pyx_v_ndim); - for (__pyx_t_3 = __pyx_v_suboffsets; __pyx_t_3 < __pyx_t_2; __pyx_t_3++) { - __pyx_t_1 = __pyx_t_3; - __pyx_v_suboffset = (__pyx_t_1[0]); - - /* "View.MemoryView":702 - * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: # <<<<<<<<<<<<<< - * raise ValueError("Indirect dimensions not supported") - * - */ - __pyx_t_4 = ((__pyx_v_suboffset >= 0) != 0); - if (unlikely(__pyx_t_4)) { - - /* "View.MemoryView":703 - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: - * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 703, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_Raise(__pyx_t_5, 0, 0, 0); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __PYX_ERR(2, 703, __pyx_L1_error) - - /* "View.MemoryView":702 - * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: # <<<<<<<<<<<<<< - * raise ValueError("Indirect dimensions not supported") - * - */ - } - } - - /* "View.MemoryView":700 - * return have_slices or nslices, tuple(result) - * - * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<< - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":710 - * - * @cname('__pyx_memview_slice') - * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<< - * cdef int new_ndim = 0, suboffset_dim = -1, dim - * cdef bint negative_step - */ - -static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) { - int __pyx_v_new_ndim; - int __pyx_v_suboffset_dim; - int __pyx_v_dim; - __Pyx_memviewslice __pyx_v_src; - __Pyx_memviewslice __pyx_v_dst; - __Pyx_memviewslice *__pyx_v_p_src; - struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0; - __Pyx_memviewslice *__pyx_v_p_dst; - int *__pyx_v_p_suboffset_dim; - Py_ssize_t __pyx_v_start; - Py_ssize_t __pyx_v_stop; - Py_ssize_t __pyx_v_step; - int __pyx_v_have_start; - int __pyx_v_have_stop; - int __pyx_v_have_step; - PyObject *__pyx_v_index = NULL; - struct __pyx_memoryview_obj *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - struct __pyx_memoryview_obj *__pyx_t_4; - char *__pyx_t_5; - int __pyx_t_6; - Py_ssize_t __pyx_t_7; - PyObject *(*__pyx_t_8)(PyObject *); - PyObject *__pyx_t_9 = NULL; - Py_ssize_t __pyx_t_10; - int __pyx_t_11; - Py_ssize_t __pyx_t_12; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memview_slice", 0); - - /* "View.MemoryView":711 - * @cname('__pyx_memview_slice') - * cdef memoryview memview_slice(memoryview memview, object indices): - * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<< - * cdef bint negative_step - * cdef __Pyx_memviewslice src, dst - */ - __pyx_v_new_ndim = 0; - __pyx_v_suboffset_dim = -1; - - /* "View.MemoryView":718 - * - * - * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<< - * - * cdef _memoryviewslice memviewsliceobj - */ - (void)(memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)))); - - /* "View.MemoryView":722 - * cdef _memoryviewslice memviewsliceobj - * - * assert memview.view.ndim > 0 # <<<<<<<<<<<<<< - * - * if isinstance(memview, _memoryviewslice): - */ - #ifndef CYTHON_WITHOUT_ASSERTIONS - if (unlikely(!Py_OptimizeFlag)) { - if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) { - PyErr_SetNone(PyExc_AssertionError); - __PYX_ERR(2, 722, __pyx_L1_error) - } - } - #endif - - /* "View.MemoryView":724 - * assert memview.view.ndim > 0 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * memviewsliceobj = memview - * p_src = &memviewsliceobj.from_slice - */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":725 - * - * if isinstance(memview, _memoryviewslice): - * memviewsliceobj = memview # <<<<<<<<<<<<<< - * p_src = &memviewsliceobj.from_slice - * else: - */ - if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) __PYX_ERR(2, 725, __pyx_L1_error) - __pyx_t_3 = ((PyObject *)__pyx_v_memview); - __Pyx_INCREF(__pyx_t_3); - __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":726 - * if isinstance(memview, _memoryviewslice): - * memviewsliceobj = memview - * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<< - * else: - * slice_copy(memview, &src) - */ - __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice); - - /* "View.MemoryView":724 - * assert memview.view.ndim > 0 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * memviewsliceobj = memview - * p_src = &memviewsliceobj.from_slice - */ - goto __pyx_L3; - } - - /* "View.MemoryView":728 - * p_src = &memviewsliceobj.from_slice - * else: - * slice_copy(memview, &src) # <<<<<<<<<<<<<< - * p_src = &src - * - */ - /*else*/ { - __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src)); - - /* "View.MemoryView":729 - * else: - * slice_copy(memview, &src) - * p_src = &src # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_p_src = (&__pyx_v_src); - } - __pyx_L3:; - - /* "View.MemoryView":735 - * - * - * dst.memview = p_src.memview # <<<<<<<<<<<<<< - * dst.data = p_src.data - * - */ - __pyx_t_4 = __pyx_v_p_src->memview; - __pyx_v_dst.memview = __pyx_t_4; - - /* "View.MemoryView":736 - * - * dst.memview = p_src.memview - * dst.data = p_src.data # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_5 = __pyx_v_p_src->data; - __pyx_v_dst.data = __pyx_t_5; - - /* "View.MemoryView":741 - * - * - * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<< - * cdef int *p_suboffset_dim = &suboffset_dim - * cdef Py_ssize_t start, stop, step - */ - __pyx_v_p_dst = (&__pyx_v_dst); - - /* "View.MemoryView":742 - * - * cdef __Pyx_memviewslice *p_dst = &dst - * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<< - * cdef Py_ssize_t start, stop, step - * cdef bint have_start, have_stop, have_step - */ - __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim); - - /* "View.MemoryView":746 - * cdef bint have_start, have_stop, have_step - * - * for dim, index in enumerate(indices): # <<<<<<<<<<<<<< - * if PyIndex_Check(index): - * slice_memviewslice( - */ - __pyx_t_6 = 0; - if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) { - __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0; - __pyx_t_8 = NULL; - } else { - __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 746, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 746, __pyx_L1_error) - } - for (;;) { - if (likely(!__pyx_t_8)) { - if (likely(PyList_CheckExact(__pyx_t_3))) { - if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) __PYX_ERR(2, 746, __pyx_L1_error) - #else - __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 746, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - #endif - } else { - if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) __PYX_ERR(2, 746, __pyx_L1_error) - #else - __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 746, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - #endif - } - } else { - __pyx_t_9 = __pyx_t_8(__pyx_t_3); - if (unlikely(!__pyx_t_9)) { - PyObject* exc_type = PyErr_Occurred(); - if (exc_type) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); - else __PYX_ERR(2, 746, __pyx_L1_error) - } - break; - } - __Pyx_GOTREF(__pyx_t_9); - } - __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9); - __pyx_t_9 = 0; - __pyx_v_dim = __pyx_t_6; - __pyx_t_6 = (__pyx_t_6 + 1); - - /* "View.MemoryView":747 - * - * for dim, index in enumerate(indices): - * if PyIndex_Check(index): # <<<<<<<<<<<<<< - * slice_memviewslice( - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], - */ - __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":751 - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], - * dim, new_ndim, p_suboffset_dim, - * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<< - * 0, 0, 0, # have_{start,stop,step} - * False) - */ - __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 751, __pyx_L1_error) - - /* "View.MemoryView":748 - * for dim, index in enumerate(indices): - * if PyIndex_Check(index): - * slice_memviewslice( # <<<<<<<<<<<<<< - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], - * dim, new_ndim, p_suboffset_dim, - */ - __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(2, 748, __pyx_L1_error) - - /* "View.MemoryView":747 - * - * for dim, index in enumerate(indices): - * if PyIndex_Check(index): # <<<<<<<<<<<<<< - * slice_memviewslice( - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], - */ - goto __pyx_L6; - } - - /* "View.MemoryView":754 - * 0, 0, 0, # have_{start,stop,step} - * False) - * elif index is None: # <<<<<<<<<<<<<< - * p_dst.shape[new_ndim] = 1 - * p_dst.strides[new_ndim] = 0 - */ - __pyx_t_2 = (__pyx_v_index == Py_None); - __pyx_t_1 = (__pyx_t_2 != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":755 - * False) - * elif index is None: - * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<< - * p_dst.strides[new_ndim] = 0 - * p_dst.suboffsets[new_ndim] = -1 - */ - (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1; - - /* "View.MemoryView":756 - * elif index is None: - * p_dst.shape[new_ndim] = 1 - * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<< - * p_dst.suboffsets[new_ndim] = -1 - * new_ndim += 1 - */ - (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0; - - /* "View.MemoryView":757 - * p_dst.shape[new_ndim] = 1 - * p_dst.strides[new_ndim] = 0 - * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<< - * new_ndim += 1 - * else: - */ - (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1L; - - /* "View.MemoryView":758 - * p_dst.strides[new_ndim] = 0 - * p_dst.suboffsets[new_ndim] = -1 - * new_ndim += 1 # <<<<<<<<<<<<<< - * else: - * start = index.start or 0 - */ - __pyx_v_new_ndim = (__pyx_v_new_ndim + 1); - - /* "View.MemoryView":754 - * 0, 0, 0, # have_{start,stop,step} - * False) - * elif index is None: # <<<<<<<<<<<<<< - * p_dst.shape[new_ndim] = 1 - * p_dst.strides[new_ndim] = 0 - */ - goto __pyx_L6; - } - - /* "View.MemoryView":760 - * new_ndim += 1 - * else: - * start = index.start or 0 # <<<<<<<<<<<<<< - * stop = index.stop or 0 - * step = index.step or 0 - */ - /*else*/ { - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 760, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 760, __pyx_L1_error) - if (!__pyx_t_1) { - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } else { - __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 760, __pyx_L1_error) - __pyx_t_10 = __pyx_t_12; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - goto __pyx_L7_bool_binop_done; - } - __pyx_t_10 = 0; - __pyx_L7_bool_binop_done:; - __pyx_v_start = __pyx_t_10; - - /* "View.MemoryView":761 - * else: - * start = index.start or 0 - * stop = index.stop or 0 # <<<<<<<<<<<<<< - * step = index.step or 0 - * - */ - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 761, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 761, __pyx_L1_error) - if (!__pyx_t_1) { - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } else { - __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 761, __pyx_L1_error) - __pyx_t_10 = __pyx_t_12; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_10 = 0; - __pyx_L9_bool_binop_done:; - __pyx_v_stop = __pyx_t_10; - - /* "View.MemoryView":762 - * start = index.start or 0 - * stop = index.stop or 0 - * step = index.step or 0 # <<<<<<<<<<<<<< - * - * have_start = index.start is not None - */ - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 762, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 762, __pyx_L1_error) - if (!__pyx_t_1) { - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - } else { - __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 762, __pyx_L1_error) - __pyx_t_10 = __pyx_t_12; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - goto __pyx_L11_bool_binop_done; - } - __pyx_t_10 = 0; - __pyx_L11_bool_binop_done:; - __pyx_v_step = __pyx_t_10; - - /* "View.MemoryView":764 - * step = index.step or 0 - * - * have_start = index.start is not None # <<<<<<<<<<<<<< - * have_stop = index.stop is not None - * have_step = index.step is not None - */ - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 764, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = (__pyx_t_9 != Py_None); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __pyx_v_have_start = __pyx_t_1; - - /* "View.MemoryView":765 - * - * have_start = index.start is not None - * have_stop = index.stop is not None # <<<<<<<<<<<<<< - * have_step = index.step is not None - * - */ - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 765, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = (__pyx_t_9 != Py_None); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __pyx_v_have_stop = __pyx_t_1; - - /* "View.MemoryView":766 - * have_start = index.start is not None - * have_stop = index.stop is not None - * have_step = index.step is not None # <<<<<<<<<<<<<< - * - * slice_memviewslice( - */ - __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 766, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_1 = (__pyx_t_9 != Py_None); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __pyx_v_have_step = __pyx_t_1; - - /* "View.MemoryView":768 - * have_step = index.step is not None - * - * slice_memviewslice( # <<<<<<<<<<<<<< - * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], - * dim, new_ndim, p_suboffset_dim, - */ - __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(2, 768, __pyx_L1_error) - - /* "View.MemoryView":774 - * have_start, have_stop, have_step, - * True) - * new_ndim += 1 # <<<<<<<<<<<<<< - * - * if isinstance(memview, _memoryviewslice): - */ - __pyx_v_new_ndim = (__pyx_v_new_ndim + 1); - } - __pyx_L6:; - - /* "View.MemoryView":746 - * cdef bint have_start, have_stop, have_step - * - * for dim, index in enumerate(indices): # <<<<<<<<<<<<<< - * if PyIndex_Check(index): - * slice_memviewslice( - */ - } - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "View.MemoryView":776 - * new_ndim += 1 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * return memoryview_fromslice(dst, new_ndim, - * memviewsliceobj.to_object_func, - */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":777 - * - * if isinstance(memview, _memoryviewslice): - * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<< - * memviewsliceobj.to_object_func, - * memviewsliceobj.to_dtype_func, - */ - __Pyx_XDECREF(((PyObject *)__pyx_r)); - - /* "View.MemoryView":778 - * if isinstance(memview, _memoryviewslice): - * return memoryview_fromslice(dst, new_ndim, - * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<< - * memviewsliceobj.to_dtype_func, - * memview.dtype_is_object) - */ - if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); __PYX_ERR(2, 778, __pyx_L1_error) } - - /* "View.MemoryView":779 - * return memoryview_fromslice(dst, new_ndim, - * memviewsliceobj.to_object_func, - * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<< - * memview.dtype_is_object) - * else: - */ - if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); __PYX_ERR(2, 779, __pyx_L1_error) } - - /* "View.MemoryView":777 - * - * if isinstance(memview, _memoryviewslice): - * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<< - * memviewsliceobj.to_object_func, - * memviewsliceobj.to_dtype_func, - */ - __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 777, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) __PYX_ERR(2, 777, __pyx_L1_error) - __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3); - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "View.MemoryView":776 - * new_ndim += 1 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * return memoryview_fromslice(dst, new_ndim, - * memviewsliceobj.to_object_func, - */ - } - - /* "View.MemoryView":782 - * memview.dtype_is_object) - * else: - * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<< - * memview.dtype_is_object) - * - */ - /*else*/ { - __Pyx_XDECREF(((PyObject *)__pyx_r)); - - /* "View.MemoryView":783 - * else: - * return memoryview_fromslice(dst, new_ndim, NULL, NULL, - * memview.dtype_is_object) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 782, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - - /* "View.MemoryView":782 - * memview.dtype_is_object) - * else: - * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<< - * memview.dtype_is_object) - * - */ - if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) __PYX_ERR(2, 782, __pyx_L1_error) - __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3); - __pyx_t_3 = 0; - goto __pyx_L0; - } - - /* "View.MemoryView":710 - * - * @cname('__pyx_memview_slice') - * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<< - * cdef int new_ndim = 0, suboffset_dim = -1, dim - * cdef bint negative_step - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj); - __Pyx_XDECREF(__pyx_v_index); - __Pyx_XGIVEREF((PyObject *)__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":807 - * - * @cname('__pyx_memoryview_slice_memviewslice') - * cdef int slice_memviewslice( # <<<<<<<<<<<<<< - * __Pyx_memviewslice *dst, - * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset, - */ - -static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) { - Py_ssize_t __pyx_v_new_shape; - int __pyx_v_negative_step; - int __pyx_r; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - - /* "View.MemoryView":827 - * cdef bint negative_step - * - * if not is_slice: # <<<<<<<<<<<<<< - * - * if start < 0: - */ - __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":829 - * if not is_slice: - * - * if start < 0: # <<<<<<<<<<<<<< - * start += shape - * if not 0 <= start < shape: - */ - __pyx_t_1 = ((__pyx_v_start < 0) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":830 - * - * if start < 0: - * start += shape # <<<<<<<<<<<<<< - * if not 0 <= start < shape: - * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) - */ - __pyx_v_start = (__pyx_v_start + __pyx_v_shape); - - /* "View.MemoryView":829 - * if not is_slice: - * - * if start < 0: # <<<<<<<<<<<<<< - * start += shape - * if not 0 <= start < shape: - */ - } - - /* "View.MemoryView":831 - * if start < 0: - * start += shape - * if not 0 <= start < shape: # <<<<<<<<<<<<<< - * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) - * else: - */ - __pyx_t_1 = (0 <= __pyx_v_start); - if (__pyx_t_1) { - __pyx_t_1 = (__pyx_v_start < __pyx_v_shape); - } - __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":832 - * start += shape - * if not 0 <= start < shape: - * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<< - * else: - * - */ - __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, ((char *)"Index out of bounds (axis %d)"), __pyx_v_dim); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(2, 832, __pyx_L1_error) - - /* "View.MemoryView":831 - * if start < 0: - * start += shape - * if not 0 <= start < shape: # <<<<<<<<<<<<<< - * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) - * else: - */ - } - - /* "View.MemoryView":827 - * cdef bint negative_step - * - * if not is_slice: # <<<<<<<<<<<<<< - * - * if start < 0: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":835 - * else: - * - * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<< - * - * if have_step and step == 0: - */ - /*else*/ { - __pyx_t_1 = ((__pyx_v_have_step != 0) != 0); - if (__pyx_t_1) { - } else { - __pyx_t_2 = __pyx_t_1; - goto __pyx_L6_bool_binop_done; - } - __pyx_t_1 = ((__pyx_v_step < 0) != 0); - __pyx_t_2 = __pyx_t_1; - __pyx_L6_bool_binop_done:; - __pyx_v_negative_step = __pyx_t_2; - - /* "View.MemoryView":837 - * negative_step = have_step != 0 and step < 0 - * - * if have_step and step == 0: # <<<<<<<<<<<<<< - * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) - * - */ - __pyx_t_1 = (__pyx_v_have_step != 0); - if (__pyx_t_1) { - } else { - __pyx_t_2 = __pyx_t_1; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_1 = ((__pyx_v_step == 0) != 0); - __pyx_t_2 = __pyx_t_1; - __pyx_L9_bool_binop_done:; - if (__pyx_t_2) { - - /* "View.MemoryView":838 - * - * if have_step and step == 0: - * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, ((char *)"Step may not be zero (axis %d)"), __pyx_v_dim); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(2, 838, __pyx_L1_error) - - /* "View.MemoryView":837 - * negative_step = have_step != 0 and step < 0 - * - * if have_step and step == 0: # <<<<<<<<<<<<<< - * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) - * - */ - } - - /* "View.MemoryView":841 - * - * - * if have_start: # <<<<<<<<<<<<<< - * if start < 0: - * start += shape - */ - __pyx_t_2 = (__pyx_v_have_start != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":842 - * - * if have_start: - * if start < 0: # <<<<<<<<<<<<<< - * start += shape - * if start < 0: - */ - __pyx_t_2 = ((__pyx_v_start < 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":843 - * if have_start: - * if start < 0: - * start += shape # <<<<<<<<<<<<<< - * if start < 0: - * start = 0 - */ - __pyx_v_start = (__pyx_v_start + __pyx_v_shape); - - /* "View.MemoryView":844 - * if start < 0: - * start += shape - * if start < 0: # <<<<<<<<<<<<<< - * start = 0 - * elif start >= shape: - */ - __pyx_t_2 = ((__pyx_v_start < 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":845 - * start += shape - * if start < 0: - * start = 0 # <<<<<<<<<<<<<< - * elif start >= shape: - * if negative_step: - */ - __pyx_v_start = 0; - - /* "View.MemoryView":844 - * if start < 0: - * start += shape - * if start < 0: # <<<<<<<<<<<<<< - * start = 0 - * elif start >= shape: - */ - } - - /* "View.MemoryView":842 - * - * if have_start: - * if start < 0: # <<<<<<<<<<<<<< - * start += shape - * if start < 0: - */ - goto __pyx_L12; - } - - /* "View.MemoryView":846 - * if start < 0: - * start = 0 - * elif start >= shape: # <<<<<<<<<<<<<< - * if negative_step: - * start = shape - 1 - */ - __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":847 - * start = 0 - * elif start >= shape: - * if negative_step: # <<<<<<<<<<<<<< - * start = shape - 1 - * else: - */ - __pyx_t_2 = (__pyx_v_negative_step != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":848 - * elif start >= shape: - * if negative_step: - * start = shape - 1 # <<<<<<<<<<<<<< - * else: - * start = shape - */ - __pyx_v_start = (__pyx_v_shape - 1); - - /* "View.MemoryView":847 - * start = 0 - * elif start >= shape: - * if negative_step: # <<<<<<<<<<<<<< - * start = shape - 1 - * else: - */ - goto __pyx_L14; - } - - /* "View.MemoryView":850 - * start = shape - 1 - * else: - * start = shape # <<<<<<<<<<<<<< - * else: - * if negative_step: - */ - /*else*/ { - __pyx_v_start = __pyx_v_shape; - } - __pyx_L14:; - - /* "View.MemoryView":846 - * if start < 0: - * start = 0 - * elif start >= shape: # <<<<<<<<<<<<<< - * if negative_step: - * start = shape - 1 - */ - } - __pyx_L12:; - - /* "View.MemoryView":841 - * - * - * if have_start: # <<<<<<<<<<<<<< - * if start < 0: - * start += shape - */ - goto __pyx_L11; - } - - /* "View.MemoryView":852 - * start = shape - * else: - * if negative_step: # <<<<<<<<<<<<<< - * start = shape - 1 - * else: - */ - /*else*/ { - __pyx_t_2 = (__pyx_v_negative_step != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":853 - * else: - * if negative_step: - * start = shape - 1 # <<<<<<<<<<<<<< - * else: - * start = 0 - */ - __pyx_v_start = (__pyx_v_shape - 1); - - /* "View.MemoryView":852 - * start = shape - * else: - * if negative_step: # <<<<<<<<<<<<<< - * start = shape - 1 - * else: - */ - goto __pyx_L15; - } - - /* "View.MemoryView":855 - * start = shape - 1 - * else: - * start = 0 # <<<<<<<<<<<<<< - * - * if have_stop: - */ - /*else*/ { - __pyx_v_start = 0; - } - __pyx_L15:; - } - __pyx_L11:; - - /* "View.MemoryView":857 - * start = 0 - * - * if have_stop: # <<<<<<<<<<<<<< - * if stop < 0: - * stop += shape - */ - __pyx_t_2 = (__pyx_v_have_stop != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":858 - * - * if have_stop: - * if stop < 0: # <<<<<<<<<<<<<< - * stop += shape - * if stop < 0: - */ - __pyx_t_2 = ((__pyx_v_stop < 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":859 - * if have_stop: - * if stop < 0: - * stop += shape # <<<<<<<<<<<<<< - * if stop < 0: - * stop = 0 - */ - __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape); - - /* "View.MemoryView":860 - * if stop < 0: - * stop += shape - * if stop < 0: # <<<<<<<<<<<<<< - * stop = 0 - * elif stop > shape: - */ - __pyx_t_2 = ((__pyx_v_stop < 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":861 - * stop += shape - * if stop < 0: - * stop = 0 # <<<<<<<<<<<<<< - * elif stop > shape: - * stop = shape - */ - __pyx_v_stop = 0; - - /* "View.MemoryView":860 - * if stop < 0: - * stop += shape - * if stop < 0: # <<<<<<<<<<<<<< - * stop = 0 - * elif stop > shape: - */ - } - - /* "View.MemoryView":858 - * - * if have_stop: - * if stop < 0: # <<<<<<<<<<<<<< - * stop += shape - * if stop < 0: - */ - goto __pyx_L17; - } - - /* "View.MemoryView":862 - * if stop < 0: - * stop = 0 - * elif stop > shape: # <<<<<<<<<<<<<< - * stop = shape - * else: - */ - __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":863 - * stop = 0 - * elif stop > shape: - * stop = shape # <<<<<<<<<<<<<< - * else: - * if negative_step: - */ - __pyx_v_stop = __pyx_v_shape; - - /* "View.MemoryView":862 - * if stop < 0: - * stop = 0 - * elif stop > shape: # <<<<<<<<<<<<<< - * stop = shape - * else: - */ - } - __pyx_L17:; - - /* "View.MemoryView":857 - * start = 0 - * - * if have_stop: # <<<<<<<<<<<<<< - * if stop < 0: - * stop += shape - */ - goto __pyx_L16; - } - - /* "View.MemoryView":865 - * stop = shape - * else: - * if negative_step: # <<<<<<<<<<<<<< - * stop = -1 - * else: - */ - /*else*/ { - __pyx_t_2 = (__pyx_v_negative_step != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":866 - * else: - * if negative_step: - * stop = -1 # <<<<<<<<<<<<<< - * else: - * stop = shape - */ - __pyx_v_stop = -1L; - - /* "View.MemoryView":865 - * stop = shape - * else: - * if negative_step: # <<<<<<<<<<<<<< - * stop = -1 - * else: - */ - goto __pyx_L19; - } - - /* "View.MemoryView":868 - * stop = -1 - * else: - * stop = shape # <<<<<<<<<<<<<< - * - * if not have_step: - */ - /*else*/ { - __pyx_v_stop = __pyx_v_shape; - } - __pyx_L19:; - } - __pyx_L16:; - - /* "View.MemoryView":870 - * stop = shape - * - * if not have_step: # <<<<<<<<<<<<<< - * step = 1 - * - */ - __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":871 - * - * if not have_step: - * step = 1 # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_step = 1; - - /* "View.MemoryView":870 - * stop = shape - * - * if not have_step: # <<<<<<<<<<<<<< - * step = 1 - * - */ - } - - /* "View.MemoryView":875 - * - * with cython.cdivision(True): - * new_shape = (stop - start) // step # <<<<<<<<<<<<<< - * - * if (stop - start) - step * new_shape: - */ - __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step); - - /* "View.MemoryView":877 - * new_shape = (stop - start) // step - * - * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<< - * new_shape += 1 - * - */ - __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":878 - * - * if (stop - start) - step * new_shape: - * new_shape += 1 # <<<<<<<<<<<<<< - * - * if new_shape < 0: - */ - __pyx_v_new_shape = (__pyx_v_new_shape + 1); - - /* "View.MemoryView":877 - * new_shape = (stop - start) // step - * - * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<< - * new_shape += 1 - * - */ - } - - /* "View.MemoryView":880 - * new_shape += 1 - * - * if new_shape < 0: # <<<<<<<<<<<<<< - * new_shape = 0 - * - */ - __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":881 - * - * if new_shape < 0: - * new_shape = 0 # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_new_shape = 0; - - /* "View.MemoryView":880 - * new_shape += 1 - * - * if new_shape < 0: # <<<<<<<<<<<<<< - * new_shape = 0 - * - */ - } - - /* "View.MemoryView":884 - * - * - * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<< - * dst.shape[new_ndim] = new_shape - * dst.suboffsets[new_ndim] = suboffset - */ - (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step); - - /* "View.MemoryView":885 - * - * dst.strides[new_ndim] = stride * step - * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<< - * dst.suboffsets[new_ndim] = suboffset - * - */ - (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape; - - /* "View.MemoryView":886 - * dst.strides[new_ndim] = stride * step - * dst.shape[new_ndim] = new_shape - * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<< - * - * - */ - (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset; - } - __pyx_L3:; - - /* "View.MemoryView":889 - * - * - * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<< - * dst.data += start * stride - * else: - */ - __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":890 - * - * if suboffset_dim[0] < 0: - * dst.data += start * stride # <<<<<<<<<<<<<< - * else: - * dst.suboffsets[suboffset_dim[0]] += start * stride - */ - __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride)); - - /* "View.MemoryView":889 - * - * - * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<< - * dst.data += start * stride - * else: - */ - goto __pyx_L23; - } - - /* "View.MemoryView":892 - * dst.data += start * stride - * else: - * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<< - * - * if suboffset >= 0: - */ - /*else*/ { - __pyx_t_3 = (__pyx_v_suboffset_dim[0]); - (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride)); - } - __pyx_L23:; - - /* "View.MemoryView":894 - * dst.suboffsets[suboffset_dim[0]] += start * stride - * - * if suboffset >= 0: # <<<<<<<<<<<<<< - * if not is_slice: - * if new_ndim == 0: - */ - __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":895 - * - * if suboffset >= 0: - * if not is_slice: # <<<<<<<<<<<<<< - * if new_ndim == 0: - * dst.data = ( dst.data)[0] + suboffset - */ - __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":896 - * if suboffset >= 0: - * if not is_slice: - * if new_ndim == 0: # <<<<<<<<<<<<<< - * dst.data = ( dst.data)[0] + suboffset - * else: - */ - __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":897 - * if not is_slice: - * if new_ndim == 0: - * dst.data = ( dst.data)[0] + suboffset # <<<<<<<<<<<<<< - * else: - * _err_dim(IndexError, "All dimensions preceding dimension %d " - */ - __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset); - - /* "View.MemoryView":896 - * if suboffset >= 0: - * if not is_slice: - * if new_ndim == 0: # <<<<<<<<<<<<<< - * dst.data = ( dst.data)[0] + suboffset - * else: - */ - goto __pyx_L26; - } - - /* "View.MemoryView":899 - * dst.data = ( dst.data)[0] + suboffset - * else: - * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<< - * "must be indexed and not sliced", dim) - * else: - */ - /*else*/ { - - /* "View.MemoryView":900 - * else: - * _err_dim(IndexError, "All dimensions preceding dimension %d " - * "must be indexed and not sliced", dim) # <<<<<<<<<<<<<< - * else: - * suboffset_dim[0] = new_ndim - */ - __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, ((char *)"All dimensions preceding dimension %d must be indexed and not sliced"), __pyx_v_dim); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(2, 899, __pyx_L1_error) - } - __pyx_L26:; - - /* "View.MemoryView":895 - * - * if suboffset >= 0: - * if not is_slice: # <<<<<<<<<<<<<< - * if new_ndim == 0: - * dst.data = ( dst.data)[0] + suboffset - */ - goto __pyx_L25; - } - - /* "View.MemoryView":902 - * "must be indexed and not sliced", dim) - * else: - * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<< - * - * return 0 - */ - /*else*/ { - (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim; - } - __pyx_L25:; - - /* "View.MemoryView":894 - * dst.suboffsets[suboffset_dim[0]] += start * stride - * - * if suboffset >= 0: # <<<<<<<<<<<<<< - * if not is_slice: - * if new_ndim == 0: - */ - } - - /* "View.MemoryView":904 - * suboffset_dim[0] = new_ndim - * - * return 0 # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "View.MemoryView":807 - * - * @cname('__pyx_memoryview_slice_memviewslice') - * cdef int slice_memviewslice( # <<<<<<<<<<<<<< - * __Pyx_memviewslice *dst, - * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset, - */ - - /* function exit code */ - __pyx_L1_error:; - { - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - } - __pyx_r = -1; - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":910 - * - * @cname('__pyx_pybuffer_index') - * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<< - * Py_ssize_t dim) except NULL: - * cdef Py_ssize_t shape, stride, suboffset = -1 - */ - -static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) { - Py_ssize_t __pyx_v_shape; - Py_ssize_t __pyx_v_stride; - Py_ssize_t __pyx_v_suboffset; - Py_ssize_t __pyx_v_itemsize; - char *__pyx_v_resultp; - char *__pyx_r; - __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("pybuffer_index", 0); - - /* "View.MemoryView":912 - * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, - * Py_ssize_t dim) except NULL: - * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<< - * cdef Py_ssize_t itemsize = view.itemsize - * cdef char *resultp - */ - __pyx_v_suboffset = -1L; - - /* "View.MemoryView":913 - * Py_ssize_t dim) except NULL: - * cdef Py_ssize_t shape, stride, suboffset = -1 - * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<< - * cdef char *resultp - * - */ - __pyx_t_1 = __pyx_v_view->itemsize; - __pyx_v_itemsize = __pyx_t_1; - - /* "View.MemoryView":916 - * cdef char *resultp - * - * if view.ndim == 0: # <<<<<<<<<<<<<< - * shape = view.len / itemsize - * stride = itemsize - */ - __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":917 - * - * if view.ndim == 0: - * shape = view.len / itemsize # <<<<<<<<<<<<<< - * stride = itemsize - * else: - */ - if (unlikely(__pyx_v_itemsize == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); - __PYX_ERR(2, 917, __pyx_L1_error) - } - else if (sizeof(Py_ssize_t) == sizeof(long) && (!(((Py_ssize_t)-1) > 0)) && unlikely(__pyx_v_itemsize == (Py_ssize_t)-1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) { - PyErr_SetString(PyExc_OverflowError, "value too large to perform division"); - __PYX_ERR(2, 917, __pyx_L1_error) - } - __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize); - - /* "View.MemoryView":918 - * if view.ndim == 0: - * shape = view.len / itemsize - * stride = itemsize # <<<<<<<<<<<<<< - * else: - * shape = view.shape[dim] - */ - __pyx_v_stride = __pyx_v_itemsize; - - /* "View.MemoryView":916 - * cdef char *resultp - * - * if view.ndim == 0: # <<<<<<<<<<<<<< - * shape = view.len / itemsize - * stride = itemsize - */ - goto __pyx_L3; - } - - /* "View.MemoryView":920 - * stride = itemsize - * else: - * shape = view.shape[dim] # <<<<<<<<<<<<<< - * stride = view.strides[dim] - * if view.suboffsets != NULL: - */ - /*else*/ { - __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]); - - /* "View.MemoryView":921 - * else: - * shape = view.shape[dim] - * stride = view.strides[dim] # <<<<<<<<<<<<<< - * if view.suboffsets != NULL: - * suboffset = view.suboffsets[dim] - */ - __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]); - - /* "View.MemoryView":922 - * shape = view.shape[dim] - * stride = view.strides[dim] - * if view.suboffsets != NULL: # <<<<<<<<<<<<<< - * suboffset = view.suboffsets[dim] - * - */ - __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":923 - * stride = view.strides[dim] - * if view.suboffsets != NULL: - * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<< - * - * if index < 0: - */ - __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]); - - /* "View.MemoryView":922 - * shape = view.shape[dim] - * stride = view.strides[dim] - * if view.suboffsets != NULL: # <<<<<<<<<<<<<< - * suboffset = view.suboffsets[dim] - * - */ - } - } - __pyx_L3:; - - /* "View.MemoryView":925 - * suboffset = view.suboffsets[dim] - * - * if index < 0: # <<<<<<<<<<<<<< - * index += view.shape[dim] - * if index < 0: - */ - __pyx_t_2 = ((__pyx_v_index < 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":926 - * - * if index < 0: - * index += view.shape[dim] # <<<<<<<<<<<<<< - * if index < 0: - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) - */ - __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim])); - - /* "View.MemoryView":927 - * if index < 0: - * index += view.shape[dim] - * if index < 0: # <<<<<<<<<<<<<< - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) - * - */ - __pyx_t_2 = ((__pyx_v_index < 0) != 0); - if (unlikely(__pyx_t_2)) { - - /* "View.MemoryView":928 - * index += view.shape[dim] - * if index < 0: - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<< - * - * if index >= shape: - */ - __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 928, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 928, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_IndexError, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 928, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 928, __pyx_L1_error) - - /* "View.MemoryView":927 - * if index < 0: - * index += view.shape[dim] - * if index < 0: # <<<<<<<<<<<<<< - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) - * - */ - } - - /* "View.MemoryView":925 - * suboffset = view.suboffsets[dim] - * - * if index < 0: # <<<<<<<<<<<<<< - * index += view.shape[dim] - * if index < 0: - */ - } - - /* "View.MemoryView":930 - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) - * - * if index >= shape: # <<<<<<<<<<<<<< - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) - * - */ - __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0); - if (unlikely(__pyx_t_2)) { - - /* "View.MemoryView":931 - * - * if index >= shape: - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<< - * - * resultp = bufp + index * stride - */ - __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 931, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 931, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_IndexError, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 931, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 931, __pyx_L1_error) - - /* "View.MemoryView":930 - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) - * - * if index >= shape: # <<<<<<<<<<<<<< - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) - * - */ - } - - /* "View.MemoryView":933 - * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) - * - * resultp = bufp + index * stride # <<<<<<<<<<<<<< - * if suboffset >= 0: - * resultp = ( resultp)[0] + suboffset - */ - __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride)); - - /* "View.MemoryView":934 - * - * resultp = bufp + index * stride - * if suboffset >= 0: # <<<<<<<<<<<<<< - * resultp = ( resultp)[0] + suboffset - * - */ - __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":935 - * resultp = bufp + index * stride - * if suboffset >= 0: - * resultp = ( resultp)[0] + suboffset # <<<<<<<<<<<<<< - * - * return resultp - */ - __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset); - - /* "View.MemoryView":934 - * - * resultp = bufp + index * stride - * if suboffset >= 0: # <<<<<<<<<<<<<< - * resultp = ( resultp)[0] + suboffset - * - */ - } - - /* "View.MemoryView":937 - * resultp = ( resultp)[0] + suboffset - * - * return resultp # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_resultp; - goto __pyx_L0; - - /* "View.MemoryView":910 - * - * @cname('__pyx_pybuffer_index') - * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<< - * Py_ssize_t dim) except NULL: - * cdef Py_ssize_t shape, stride, suboffset = -1 - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":943 - * - * @cname('__pyx_memslice_transpose') - * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<< - * cdef int ndim = memslice.memview.view.ndim - * - */ - -static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) { - int __pyx_v_ndim; - Py_ssize_t *__pyx_v_shape; - Py_ssize_t *__pyx_v_strides; - int __pyx_v_i; - int __pyx_v_j; - int __pyx_r; - int __pyx_t_1; - Py_ssize_t *__pyx_t_2; - long __pyx_t_3; - long __pyx_t_4; - Py_ssize_t __pyx_t_5; - Py_ssize_t __pyx_t_6; - int __pyx_t_7; - int __pyx_t_8; - int __pyx_t_9; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - - /* "View.MemoryView":944 - * @cname('__pyx_memslice_transpose') - * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: - * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<< - * - * cdef Py_ssize_t *shape = memslice.shape - */ - __pyx_t_1 = __pyx_v_memslice->memview->view.ndim; - __pyx_v_ndim = __pyx_t_1; - - /* "View.MemoryView":946 - * cdef int ndim = memslice.memview.view.ndim - * - * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<< - * cdef Py_ssize_t *strides = memslice.strides - * - */ - __pyx_t_2 = __pyx_v_memslice->shape; - __pyx_v_shape = __pyx_t_2; - - /* "View.MemoryView":947 - * - * cdef Py_ssize_t *shape = memslice.shape - * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_2 = __pyx_v_memslice->strides; - __pyx_v_strides = __pyx_t_2; - - /* "View.MemoryView":951 - * - * cdef int i, j - * for i in range(ndim / 2): # <<<<<<<<<<<<<< - * j = ndim - 1 - i - * strides[i], strides[j] = strides[j], strides[i] - */ - __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2); - __pyx_t_4 = __pyx_t_3; - for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_4; __pyx_t_1+=1) { - __pyx_v_i = __pyx_t_1; - - /* "View.MemoryView":952 - * cdef int i, j - * for i in range(ndim / 2): - * j = ndim - 1 - i # <<<<<<<<<<<<<< - * strides[i], strides[j] = strides[j], strides[i] - * shape[i], shape[j] = shape[j], shape[i] - */ - __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i); - - /* "View.MemoryView":953 - * for i in range(ndim / 2): - * j = ndim - 1 - i - * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<< - * shape[i], shape[j] = shape[j], shape[i] - * - */ - __pyx_t_5 = (__pyx_v_strides[__pyx_v_j]); - __pyx_t_6 = (__pyx_v_strides[__pyx_v_i]); - (__pyx_v_strides[__pyx_v_i]) = __pyx_t_5; - (__pyx_v_strides[__pyx_v_j]) = __pyx_t_6; - - /* "View.MemoryView":954 - * j = ndim - 1 - i - * strides[i], strides[j] = strides[j], strides[i] - * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<< - * - * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: - */ - __pyx_t_6 = (__pyx_v_shape[__pyx_v_j]); - __pyx_t_5 = (__pyx_v_shape[__pyx_v_i]); - (__pyx_v_shape[__pyx_v_i]) = __pyx_t_6; - (__pyx_v_shape[__pyx_v_j]) = __pyx_t_5; - - /* "View.MemoryView":956 - * shape[i], shape[j] = shape[j], shape[i] - * - * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<< - * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") - * - */ - __pyx_t_8 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0); - if (!__pyx_t_8) { - } else { - __pyx_t_7 = __pyx_t_8; - goto __pyx_L6_bool_binop_done; - } - __pyx_t_8 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0); - __pyx_t_7 = __pyx_t_8; - __pyx_L6_bool_binop_done:; - if (__pyx_t_7) { - - /* "View.MemoryView":957 - * - * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: - * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<< - * - * return 1 - */ - __pyx_t_9 = __pyx_memoryview_err(__pyx_builtin_ValueError, ((char *)"Cannot transpose memoryview with indirect dimensions")); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(2, 957, __pyx_L1_error) - - /* "View.MemoryView":956 - * shape[i], shape[j] = shape[j], shape[i] - * - * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<< - * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") - * - */ - } - } - - /* "View.MemoryView":959 - * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") - * - * return 1 # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "View.MemoryView":943 - * - * @cname('__pyx_memslice_transpose') - * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<< - * cdef int ndim = memslice.memview.view.ndim - * - */ - - /* function exit code */ - __pyx_L1_error:; - { - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - } - __pyx_r = 0; - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":976 - * cdef int (*to_dtype_func)(char *, object) except 0 - * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) - * - */ - -/* Python wrapper */ -static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__", 0); - - /* "View.MemoryView":977 - * - * def __dealloc__(self): - * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<< - * - * cdef convert_item_to_object(self, char *itemp): - */ - __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1); - - /* "View.MemoryView":976 - * cdef int (*to_dtype_func)(char *, object) except 0 - * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) - * - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "View.MemoryView":979 - * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) - * - * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< - * if self.to_object_func != NULL: - * return self.to_object_func(itemp) - */ - -static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("convert_item_to_object", 0); - - /* "View.MemoryView":980 - * - * cdef convert_item_to_object(self, char *itemp): - * if self.to_object_func != NULL: # <<<<<<<<<<<<<< - * return self.to_object_func(itemp) - * else: - */ - __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":981 - * cdef convert_item_to_object(self, char *itemp): - * if self.to_object_func != NULL: - * return self.to_object_func(itemp) # <<<<<<<<<<<<<< - * else: - * return memoryview.convert_item_to_object(self, itemp) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 981, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "View.MemoryView":980 - * - * cdef convert_item_to_object(self, char *itemp): - * if self.to_object_func != NULL: # <<<<<<<<<<<<<< - * return self.to_object_func(itemp) - * else: - */ - } - - /* "View.MemoryView":983 - * return self.to_object_func(itemp) - * else: - * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<< - * - * cdef assign_item_from_object(self, char *itemp, object value): - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 983, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - } - - /* "View.MemoryView":979 - * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) - * - * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< - * if self.to_object_func != NULL: - * return self.to_object_func(itemp) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":985 - * return memoryview.convert_item_to_object(self, itemp) - * - * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< - * if self.to_dtype_func != NULL: - * self.to_dtype_func(itemp, value) - */ - -static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("assign_item_from_object", 0); - - /* "View.MemoryView":986 - * - * cdef assign_item_from_object(self, char *itemp, object value): - * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<< - * self.to_dtype_func(itemp, value) - * else: - */ - __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":987 - * cdef assign_item_from_object(self, char *itemp, object value): - * if self.to_dtype_func != NULL: - * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<< - * else: - * memoryview.assign_item_from_object(self, itemp, value) - */ - __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(2, 987, __pyx_L1_error) - - /* "View.MemoryView":986 - * - * cdef assign_item_from_object(self, char *itemp, object value): - * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<< - * self.to_dtype_func(itemp, value) - * else: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":989 - * self.to_dtype_func(itemp, value) - * else: - * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<< - * - * @property - */ - /*else*/ { - __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 989, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - __pyx_L3:; - - /* "View.MemoryView":985 - * return memoryview.convert_item_to_object(self, itemp) - * - * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< - * if self.to_dtype_func != NULL: - * self.to_dtype_func(itemp, value) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":992 - * - * @property - * def base(self): # <<<<<<<<<<<<<< - * return self.from_object - * - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_16_memoryviewslice_4base_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_15View_dot_MemoryView_16_memoryviewslice_4base_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_15View_dot_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__", 0); - - /* "View.MemoryView":993 - * @property - * def base(self): - * return self.from_object # <<<<<<<<<<<<<< - * - * __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_self->from_object); - __pyx_r = __pyx_v_self->from_object; - goto __pyx_L0; - - /* "View.MemoryView":992 - * - * @property - * def base(self): # <<<<<<<<<<<<<< - * return self.from_object - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_memoryviewslice_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyObject *__pyx_pw___pyx_memoryviewslice_1__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_memoryviewslice___reduce_cython__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_memoryviewslice___reduce_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView._memoryviewslice.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - -/* Python wrapper */ -static PyObject *__pyx_pw___pyx_memoryviewslice_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyObject *__pyx_pw___pyx_memoryviewslice_3__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf___pyx_memoryviewslice_2__setstate_cython__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf___pyx_memoryviewslice_2__setstate_cython__(CYTHON_UNUSED struct __pyx_memoryviewslice_obj *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView._memoryviewslice.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":999 - * - * @cname('__pyx_memoryview_fromslice') - * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<< - * int ndim, - * object (*to_object_func)(char *), - */ - -static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) { - struct __pyx_memoryviewslice_obj *__pyx_v_result = 0; - Py_ssize_t __pyx_v_suboffset; - PyObject *__pyx_v_length = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - __Pyx_TypeInfo *__pyx_t_4; - Py_buffer __pyx_t_5; - Py_ssize_t *__pyx_t_6; - Py_ssize_t *__pyx_t_7; - Py_ssize_t *__pyx_t_8; - Py_ssize_t __pyx_t_9; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memoryview_fromslice", 0); - - /* "View.MemoryView":1007 - * cdef _memoryviewslice result - * - * if memviewslice.memview == Py_None: # <<<<<<<<<<<<<< - * return None - * - */ - __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":1008 - * - * if memviewslice.memview == Py_None: - * return None # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - - /* "View.MemoryView":1007 - * cdef _memoryviewslice result - * - * if memviewslice.memview == Py_None: # <<<<<<<<<<<<<< - * return None - * - */ - } - - /* "View.MemoryView":1013 - * - * - * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<< - * - * result.from_slice = memviewslice - */ - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1013, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1013, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2); - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryviewslice_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1013, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2); - __pyx_t_2 = 0; - - /* "View.MemoryView":1015 - * result = _memoryviewslice(None, 0, dtype_is_object) - * - * result.from_slice = memviewslice # <<<<<<<<<<<<<< - * __PYX_INC_MEMVIEW(&memviewslice, 1) - * - */ - __pyx_v_result->from_slice = __pyx_v_memviewslice; - - /* "View.MemoryView":1016 - * - * result.from_slice = memviewslice - * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<< - * - * result.from_object = ( memviewslice.memview).base - */ - __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1); - - /* "View.MemoryView":1018 - * __PYX_INC_MEMVIEW(&memviewslice, 1) - * - * result.from_object = ( memviewslice.memview).base # <<<<<<<<<<<<<< - * result.typeinfo = memviewslice.memview.typeinfo - * - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1018, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_v_result->from_object); - __Pyx_DECREF(__pyx_v_result->from_object); - __pyx_v_result->from_object = __pyx_t_2; - __pyx_t_2 = 0; - - /* "View.MemoryView":1019 - * - * result.from_object = ( memviewslice.memview).base - * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<< - * - * result.view = memviewslice.memview.view - */ - __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo; - __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4; - - /* "View.MemoryView":1021 - * result.typeinfo = memviewslice.memview.typeinfo - * - * result.view = memviewslice.memview.view # <<<<<<<<<<<<<< - * result.view.buf = memviewslice.data - * result.view.ndim = ndim - */ - __pyx_t_5 = __pyx_v_memviewslice.memview->view; - __pyx_v_result->__pyx_base.view = __pyx_t_5; - - /* "View.MemoryView":1022 - * - * result.view = memviewslice.memview.view - * result.view.buf = memviewslice.data # <<<<<<<<<<<<<< - * result.view.ndim = ndim - * (<__pyx_buffer *> &result.view).obj = Py_None - */ - __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data); - - /* "View.MemoryView":1023 - * result.view = memviewslice.memview.view - * result.view.buf = memviewslice.data - * result.view.ndim = ndim # <<<<<<<<<<<<<< - * (<__pyx_buffer *> &result.view).obj = Py_None - * Py_INCREF(Py_None) - */ - __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim; - - /* "View.MemoryView":1024 - * result.view.buf = memviewslice.data - * result.view.ndim = ndim - * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<< - * Py_INCREF(Py_None) - * - */ - ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None; - - /* "View.MemoryView":1025 - * result.view.ndim = ndim - * (<__pyx_buffer *> &result.view).obj = Py_None - * Py_INCREF(Py_None) # <<<<<<<<<<<<<< - * - * if (memviewslice.memview).flags & PyBUF_WRITABLE: - */ - Py_INCREF(Py_None); - - /* "View.MemoryView":1027 - * Py_INCREF(Py_None) - * - * if (memviewslice.memview).flags & PyBUF_WRITABLE: # <<<<<<<<<<<<<< - * result.flags = PyBUF_RECORDS - * else: - */ - __pyx_t_1 = ((((struct __pyx_memoryview_obj *)__pyx_v_memviewslice.memview)->flags & PyBUF_WRITABLE) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":1028 - * - * if (memviewslice.memview).flags & PyBUF_WRITABLE: - * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<< - * else: - * result.flags = PyBUF_RECORDS_RO - */ - __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS; - - /* "View.MemoryView":1027 - * Py_INCREF(Py_None) - * - * if (memviewslice.memview).flags & PyBUF_WRITABLE: # <<<<<<<<<<<<<< - * result.flags = PyBUF_RECORDS - * else: - */ - goto __pyx_L4; - } - - /* "View.MemoryView":1030 - * result.flags = PyBUF_RECORDS - * else: - * result.flags = PyBUF_RECORDS_RO # <<<<<<<<<<<<<< - * - * result.view.shape = result.from_slice.shape - */ - /*else*/ { - __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS_RO; - } - __pyx_L4:; - - /* "View.MemoryView":1032 - * result.flags = PyBUF_RECORDS_RO - * - * result.view.shape = result.from_slice.shape # <<<<<<<<<<<<<< - * result.view.strides = result.from_slice.strides - * - */ - __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape); - - /* "View.MemoryView":1033 - * - * result.view.shape = result.from_slice.shape - * result.view.strides = result.from_slice.strides # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides); - - /* "View.MemoryView":1036 - * - * - * result.view.suboffsets = NULL # <<<<<<<<<<<<<< - * for suboffset in result.from_slice.suboffsets[:ndim]: - * if suboffset >= 0: - */ - __pyx_v_result->__pyx_base.view.suboffsets = NULL; - - /* "View.MemoryView":1037 - * - * result.view.suboffsets = NULL - * for suboffset in result.from_slice.suboffsets[:ndim]: # <<<<<<<<<<<<<< - * if suboffset >= 0: - * result.view.suboffsets = result.from_slice.suboffsets - */ - __pyx_t_7 = (__pyx_v_result->from_slice.suboffsets + __pyx_v_ndim); - for (__pyx_t_8 = __pyx_v_result->from_slice.suboffsets; __pyx_t_8 < __pyx_t_7; __pyx_t_8++) { - __pyx_t_6 = __pyx_t_8; - __pyx_v_suboffset = (__pyx_t_6[0]); - - /* "View.MemoryView":1038 - * result.view.suboffsets = NULL - * for suboffset in result.from_slice.suboffsets[:ndim]: - * if suboffset >= 0: # <<<<<<<<<<<<<< - * result.view.suboffsets = result.from_slice.suboffsets - * break - */ - __pyx_t_1 = ((__pyx_v_suboffset >= 0) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":1039 - * for suboffset in result.from_slice.suboffsets[:ndim]: - * if suboffset >= 0: - * result.view.suboffsets = result.from_slice.suboffsets # <<<<<<<<<<<<<< - * break - * - */ - __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets); - - /* "View.MemoryView":1040 - * if suboffset >= 0: - * result.view.suboffsets = result.from_slice.suboffsets - * break # <<<<<<<<<<<<<< - * - * result.view.len = result.view.itemsize - */ - goto __pyx_L6_break; - - /* "View.MemoryView":1038 - * result.view.suboffsets = NULL - * for suboffset in result.from_slice.suboffsets[:ndim]: - * if suboffset >= 0: # <<<<<<<<<<<<<< - * result.view.suboffsets = result.from_slice.suboffsets - * break - */ - } - } - __pyx_L6_break:; - - /* "View.MemoryView":1042 - * break - * - * result.view.len = result.view.itemsize # <<<<<<<<<<<<<< - * for length in result.view.shape[:ndim]: - * result.view.len *= length - */ - __pyx_t_9 = __pyx_v_result->__pyx_base.view.itemsize; - __pyx_v_result->__pyx_base.view.len = __pyx_t_9; - - /* "View.MemoryView":1043 - * - * result.view.len = result.view.itemsize - * for length in result.view.shape[:ndim]: # <<<<<<<<<<<<<< - * result.view.len *= length - * - */ - __pyx_t_7 = (__pyx_v_result->__pyx_base.view.shape + __pyx_v_ndim); - for (__pyx_t_8 = __pyx_v_result->__pyx_base.view.shape; __pyx_t_8 < __pyx_t_7; __pyx_t_8++) { - __pyx_t_6 = __pyx_t_8; - __pyx_t_2 = PyInt_FromSsize_t((__pyx_t_6[0])); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1043, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_2); - __pyx_t_2 = 0; - - /* "View.MemoryView":1044 - * result.view.len = result.view.itemsize - * for length in result.view.shape[:ndim]: - * result.view.len *= length # <<<<<<<<<<<<<< - * - * result.to_object_func = to_object_func - */ - __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_result->__pyx_base.view.len); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1044, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_t_2, __pyx_v_length); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1044, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_t_3); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 1044, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_result->__pyx_base.view.len = __pyx_t_9; - } - - /* "View.MemoryView":1046 - * result.view.len *= length - * - * result.to_object_func = to_object_func # <<<<<<<<<<<<<< - * result.to_dtype_func = to_dtype_func - * - */ - __pyx_v_result->to_object_func = __pyx_v_to_object_func; - - /* "View.MemoryView":1047 - * - * result.to_object_func = to_object_func - * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<< - * - * return result - */ - __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func; - - /* "View.MemoryView":1049 - * result.to_dtype_func = to_dtype_func - * - * return result # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_get_slice_from_memoryview') - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_result)); - __pyx_r = ((PyObject *)__pyx_v_result); - goto __pyx_L0; - - /* "View.MemoryView":999 - * - * @cname('__pyx_memoryview_fromslice') - * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<< - * int ndim, - * object (*to_object_func)(char *), - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_result); - __Pyx_XDECREF(__pyx_v_length); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":1052 - * - * @cname('__pyx_memoryview_get_slice_from_memoryview') - * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *mslice) except NULL: - * cdef _memoryviewslice obj - */ - -static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) { - struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0; - __Pyx_memviewslice *__pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("get_slice_from_memview", 0); - - /* "View.MemoryView":1055 - * __Pyx_memviewslice *mslice) except NULL: - * cdef _memoryviewslice obj - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * obj = memview - * return &obj.from_slice - */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1056 - * cdef _memoryviewslice obj - * if isinstance(memview, _memoryviewslice): - * obj = memview # <<<<<<<<<<<<<< - * return &obj.from_slice - * else: - */ - if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) __PYX_ERR(2, 1056, __pyx_L1_error) - __pyx_t_3 = ((PyObject *)__pyx_v_memview); - __Pyx_INCREF(__pyx_t_3); - __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":1057 - * if isinstance(memview, _memoryviewslice): - * obj = memview - * return &obj.from_slice # <<<<<<<<<<<<<< - * else: - * slice_copy(memview, mslice) - */ - __pyx_r = (&__pyx_v_obj->from_slice); - goto __pyx_L0; - - /* "View.MemoryView":1055 - * __Pyx_memviewslice *mslice) except NULL: - * cdef _memoryviewslice obj - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * obj = memview - * return &obj.from_slice - */ - } - - /* "View.MemoryView":1059 - * return &obj.from_slice - * else: - * slice_copy(memview, mslice) # <<<<<<<<<<<<<< - * return mslice - * - */ - /*else*/ { - __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice); - - /* "View.MemoryView":1060 - * else: - * slice_copy(memview, mslice) - * return mslice # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_slice_copy') - */ - __pyx_r = __pyx_v_mslice; - goto __pyx_L0; - } - - /* "View.MemoryView":1052 - * - * @cname('__pyx_memoryview_get_slice_from_memoryview') - * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *mslice) except NULL: - * cdef _memoryviewslice obj - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_obj); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":1063 - * - * @cname('__pyx_memoryview_slice_copy') - * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<< - * cdef int dim - * cdef (Py_ssize_t*) shape, strides, suboffsets - */ - -static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) { - int __pyx_v_dim; - Py_ssize_t *__pyx_v_shape; - Py_ssize_t *__pyx_v_strides; - Py_ssize_t *__pyx_v_suboffsets; - __Pyx_RefNannyDeclarations - Py_ssize_t *__pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - Py_ssize_t __pyx_t_5; - __Pyx_RefNannySetupContext("slice_copy", 0); - - /* "View.MemoryView":1067 - * cdef (Py_ssize_t*) shape, strides, suboffsets - * - * shape = memview.view.shape # <<<<<<<<<<<<<< - * strides = memview.view.strides - * suboffsets = memview.view.suboffsets - */ - __pyx_t_1 = __pyx_v_memview->view.shape; - __pyx_v_shape = __pyx_t_1; - - /* "View.MemoryView":1068 - * - * shape = memview.view.shape - * strides = memview.view.strides # <<<<<<<<<<<<<< - * suboffsets = memview.view.suboffsets - * - */ - __pyx_t_1 = __pyx_v_memview->view.strides; - __pyx_v_strides = __pyx_t_1; - - /* "View.MemoryView":1069 - * shape = memview.view.shape - * strides = memview.view.strides - * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<< - * - * dst.memview = <__pyx_memoryview *> memview - */ - __pyx_t_1 = __pyx_v_memview->view.suboffsets; - __pyx_v_suboffsets = __pyx_t_1; - - /* "View.MemoryView":1071 - * suboffsets = memview.view.suboffsets - * - * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<< - * dst.data = memview.view.buf - * - */ - __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview); - - /* "View.MemoryView":1072 - * - * dst.memview = <__pyx_memoryview *> memview - * dst.data = memview.view.buf # <<<<<<<<<<<<<< - * - * for dim in range(memview.view.ndim): - */ - __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf); - - /* "View.MemoryView":1074 - * dst.data = memview.view.buf - * - * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<< - * dst.shape[dim] = shape[dim] - * dst.strides[dim] = strides[dim] - */ - __pyx_t_2 = __pyx_v_memview->view.ndim; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_dim = __pyx_t_4; - - /* "View.MemoryView":1075 - * - * for dim in range(memview.view.ndim): - * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<< - * dst.strides[dim] = strides[dim] - * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 - */ - (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]); - - /* "View.MemoryView":1076 - * for dim in range(memview.view.ndim): - * dst.shape[dim] = shape[dim] - * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<< - * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 - * - */ - (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]); - - /* "View.MemoryView":1077 - * dst.shape[dim] = shape[dim] - * dst.strides[dim] = strides[dim] - * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_copy_object') - */ - if ((__pyx_v_suboffsets != 0)) { - __pyx_t_5 = (__pyx_v_suboffsets[__pyx_v_dim]); - } else { - __pyx_t_5 = -1L; - } - (__pyx_v_dst->suboffsets[__pyx_v_dim]) = __pyx_t_5; - } - - /* "View.MemoryView":1063 - * - * @cname('__pyx_memoryview_slice_copy') - * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<< - * cdef int dim - * cdef (Py_ssize_t*) shape, strides, suboffsets - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "View.MemoryView":1080 - * - * @cname('__pyx_memoryview_copy_object') - * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<< - * "Create a new memoryview object" - * cdef __Pyx_memviewslice memviewslice - */ - -static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) { - __Pyx_memviewslice __pyx_v_memviewslice; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memoryview_copy", 0); - - /* "View.MemoryView":1083 - * "Create a new memoryview object" - * cdef __Pyx_memviewslice memviewslice - * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<< - * return memoryview_copy_from_slice(memview, &memviewslice) - * - */ - __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice)); - - /* "View.MemoryView":1084 - * cdef __Pyx_memviewslice memviewslice - * slice_copy(memview, &memviewslice) - * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_copy_object_from_slice') - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 1084, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "View.MemoryView":1080 - * - * @cname('__pyx_memoryview_copy_object') - * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<< - * "Create a new memoryview object" - * cdef __Pyx_memviewslice memviewslice - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":1087 - * - * @cname('__pyx_memoryview_copy_object_from_slice') - * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<< - * """ - * Create a new memoryview object from a given memoryview object and slice. - */ - -static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) { - PyObject *(*__pyx_v_to_object_func)(char *); - int (*__pyx_v_to_dtype_func)(char *, PyObject *); - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *(*__pyx_t_3)(char *); - int (*__pyx_t_4)(char *, PyObject *); - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0); - - /* "View.MemoryView":1094 - * cdef int (*to_dtype_func)(char *, object) except 0 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * to_object_func = (<_memoryviewslice> memview).to_object_func - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func - */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1095 - * - * if isinstance(memview, _memoryviewslice): - * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<< - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func - * else: - */ - __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func; - __pyx_v_to_object_func = __pyx_t_3; - - /* "View.MemoryView":1096 - * if isinstance(memview, _memoryviewslice): - * to_object_func = (<_memoryviewslice> memview).to_object_func - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<< - * else: - * to_object_func = NULL - */ - __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func; - __pyx_v_to_dtype_func = __pyx_t_4; - - /* "View.MemoryView":1094 - * cdef int (*to_dtype_func)(char *, object) except 0 - * - * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< - * to_object_func = (<_memoryviewslice> memview).to_object_func - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func - */ - goto __pyx_L3; - } - - /* "View.MemoryView":1098 - * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func - * else: - * to_object_func = NULL # <<<<<<<<<<<<<< - * to_dtype_func = NULL - * - */ - /*else*/ { - __pyx_v_to_object_func = NULL; - - /* "View.MemoryView":1099 - * else: - * to_object_func = NULL - * to_dtype_func = NULL # <<<<<<<<<<<<<< - * - * return memoryview_fromslice(memviewslice[0], memview.view.ndim, - */ - __pyx_v_to_dtype_func = NULL; - } - __pyx_L3:; - - /* "View.MemoryView":1101 - * to_dtype_func = NULL - * - * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<< - * to_object_func, to_dtype_func, - * memview.dtype_is_object) - */ - __Pyx_XDECREF(__pyx_r); - - /* "View.MemoryView":1103 - * return memoryview_fromslice(memviewslice[0], memview.view.ndim, - * to_object_func, to_dtype_func, - * memview.dtype_is_object) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 1101, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_r = __pyx_t_5; - __pyx_t_5 = 0; - goto __pyx_L0; - - /* "View.MemoryView":1087 - * - * @cname('__pyx_memoryview_copy_object_from_slice') - * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<< - * """ - * Create a new memoryview object from a given memoryview object and slice. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "View.MemoryView":1109 - * - * - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<< - * if arg < 0: - * return -arg - */ - -static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) { - Py_ssize_t __pyx_r; - int __pyx_t_1; - - /* "View.MemoryView":1110 - * - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: - * if arg < 0: # <<<<<<<<<<<<<< - * return -arg - * else: - */ - __pyx_t_1 = ((__pyx_v_arg < 0) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":1111 - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: - * if arg < 0: - * return -arg # <<<<<<<<<<<<<< - * else: - * return arg - */ - __pyx_r = (-__pyx_v_arg); - goto __pyx_L0; - - /* "View.MemoryView":1110 - * - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: - * if arg < 0: # <<<<<<<<<<<<<< - * return -arg - * else: - */ - } - - /* "View.MemoryView":1113 - * return -arg - * else: - * return arg # <<<<<<<<<<<<<< - * - * @cname('__pyx_get_best_slice_order') - */ - /*else*/ { - __pyx_r = __pyx_v_arg; - goto __pyx_L0; - } - - /* "View.MemoryView":1109 - * - * - * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<< - * if arg < 0: - * return -arg - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1116 - * - * @cname('__pyx_get_best_slice_order') - * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<< - * """ - * Figure out the best memory access order for a given slice. - */ - -static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) { - int __pyx_v_i; - Py_ssize_t __pyx_v_c_stride; - Py_ssize_t __pyx_v_f_stride; - char __pyx_r; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - - /* "View.MemoryView":1121 - * """ - * cdef int i - * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<< - * cdef Py_ssize_t f_stride = 0 - * - */ - __pyx_v_c_stride = 0; - - /* "View.MemoryView":1122 - * cdef int i - * cdef Py_ssize_t c_stride = 0 - * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<< - * - * for i in range(ndim - 1, -1, -1): - */ - __pyx_v_f_stride = 0; - - /* "View.MemoryView":1124 - * cdef Py_ssize_t f_stride = 0 - * - * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< - * if mslice.shape[i] > 1: - * c_stride = mslice.strides[i] - */ - for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) { - __pyx_v_i = __pyx_t_1; - - /* "View.MemoryView":1125 - * - * for i in range(ndim - 1, -1, -1): - * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< - * c_stride = mslice.strides[i] - * break - */ - __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1126 - * for i in range(ndim - 1, -1, -1): - * if mslice.shape[i] > 1: - * c_stride = mslice.strides[i] # <<<<<<<<<<<<<< - * break - * - */ - __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]); - - /* "View.MemoryView":1127 - * if mslice.shape[i] > 1: - * c_stride = mslice.strides[i] - * break # <<<<<<<<<<<<<< - * - * for i in range(ndim): - */ - goto __pyx_L4_break; - - /* "View.MemoryView":1125 - * - * for i in range(ndim - 1, -1, -1): - * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< - * c_stride = mslice.strides[i] - * break - */ - } - } - __pyx_L4_break:; - - /* "View.MemoryView":1129 - * break - * - * for i in range(ndim): # <<<<<<<<<<<<<< - * if mslice.shape[i] > 1: - * f_stride = mslice.strides[i] - */ - __pyx_t_1 = __pyx_v_ndim; - __pyx_t_3 = __pyx_t_1; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; - - /* "View.MemoryView":1130 - * - * for i in range(ndim): - * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< - * f_stride = mslice.strides[i] - * break - */ - __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1131 - * for i in range(ndim): - * if mslice.shape[i] > 1: - * f_stride = mslice.strides[i] # <<<<<<<<<<<<<< - * break - * - */ - __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]); - - /* "View.MemoryView":1132 - * if mslice.shape[i] > 1: - * f_stride = mslice.strides[i] - * break # <<<<<<<<<<<<<< - * - * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): - */ - goto __pyx_L7_break; - - /* "View.MemoryView":1130 - * - * for i in range(ndim): - * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< - * f_stride = mslice.strides[i] - * break - */ - } - } - __pyx_L7_break:; - - /* "View.MemoryView":1134 - * break - * - * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<< - * return 'C' - * else: - */ - __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1135 - * - * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): - * return 'C' # <<<<<<<<<<<<<< - * else: - * return 'F' - */ - __pyx_r = 'C'; - goto __pyx_L0; - - /* "View.MemoryView":1134 - * break - * - * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<< - * return 'C' - * else: - */ - } - - /* "View.MemoryView":1137 - * return 'C' - * else: - * return 'F' # <<<<<<<<<<<<<< - * - * @cython.cdivision(True) - */ - /*else*/ { - __pyx_r = 'F'; - goto __pyx_L0; - } - - /* "View.MemoryView":1116 - * - * @cname('__pyx_get_best_slice_order') - * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<< - * """ - * Figure out the best memory access order for a given slice. - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1140 - * - * @cython.cdivision(True) - * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<< - * char *dst_data, Py_ssize_t *dst_strides, - * Py_ssize_t *src_shape, Py_ssize_t *dst_shape, - */ - -static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) { - CYTHON_UNUSED Py_ssize_t __pyx_v_i; - CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent; - Py_ssize_t __pyx_v_dst_extent; - Py_ssize_t __pyx_v_src_stride; - Py_ssize_t __pyx_v_dst_stride; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - Py_ssize_t __pyx_t_4; - Py_ssize_t __pyx_t_5; - Py_ssize_t __pyx_t_6; - - /* "View.MemoryView":1147 - * - * cdef Py_ssize_t i - * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<< - * cdef Py_ssize_t dst_extent = dst_shape[0] - * cdef Py_ssize_t src_stride = src_strides[0] - */ - __pyx_v_src_extent = (__pyx_v_src_shape[0]); - - /* "View.MemoryView":1148 - * cdef Py_ssize_t i - * cdef Py_ssize_t src_extent = src_shape[0] - * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<< - * cdef Py_ssize_t src_stride = src_strides[0] - * cdef Py_ssize_t dst_stride = dst_strides[0] - */ - __pyx_v_dst_extent = (__pyx_v_dst_shape[0]); - - /* "View.MemoryView":1149 - * cdef Py_ssize_t src_extent = src_shape[0] - * cdef Py_ssize_t dst_extent = dst_shape[0] - * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<< - * cdef Py_ssize_t dst_stride = dst_strides[0] - * - */ - __pyx_v_src_stride = (__pyx_v_src_strides[0]); - - /* "View.MemoryView":1150 - * cdef Py_ssize_t dst_extent = dst_shape[0] - * cdef Py_ssize_t src_stride = src_strides[0] - * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<< - * - * if ndim == 1: - */ - __pyx_v_dst_stride = (__pyx_v_dst_strides[0]); - - /* "View.MemoryView":1152 - * cdef Py_ssize_t dst_stride = dst_strides[0] - * - * if ndim == 1: # <<<<<<<<<<<<<< - * if (src_stride > 0 and dst_stride > 0 and - * src_stride == itemsize == dst_stride): - */ - __pyx_t_1 = ((__pyx_v_ndim == 1) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":1153 - * - * if ndim == 1: - * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< - * src_stride == itemsize == dst_stride): - * memcpy(dst_data, src_data, itemsize * dst_extent) - */ - __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L5_bool_binop_done; - } - __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L5_bool_binop_done; - } - - /* "View.MemoryView":1154 - * if ndim == 1: - * if (src_stride > 0 and dst_stride > 0 and - * src_stride == itemsize == dst_stride): # <<<<<<<<<<<<<< - * memcpy(dst_data, src_data, itemsize * dst_extent) - * else: - */ - __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize); - if (__pyx_t_2) { - __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride)); - } - __pyx_t_3 = (__pyx_t_2 != 0); - __pyx_t_1 = __pyx_t_3; - __pyx_L5_bool_binop_done:; - - /* "View.MemoryView":1153 - * - * if ndim == 1: - * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< - * src_stride == itemsize == dst_stride): - * memcpy(dst_data, src_data, itemsize * dst_extent) - */ - if (__pyx_t_1) { - - /* "View.MemoryView":1155 - * if (src_stride > 0 and dst_stride > 0 and - * src_stride == itemsize == dst_stride): - * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<< - * else: - * for i in range(dst_extent): - */ - (void)(memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent))); - - /* "View.MemoryView":1153 - * - * if ndim == 1: - * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< - * src_stride == itemsize == dst_stride): - * memcpy(dst_data, src_data, itemsize * dst_extent) - */ - goto __pyx_L4; - } - - /* "View.MemoryView":1157 - * memcpy(dst_data, src_data, itemsize * dst_extent) - * else: - * for i in range(dst_extent): # <<<<<<<<<<<<<< - * memcpy(dst_data, src_data, itemsize) - * src_data += src_stride - */ - /*else*/ { - __pyx_t_4 = __pyx_v_dst_extent; - __pyx_t_5 = __pyx_t_4; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; - - /* "View.MemoryView":1158 - * else: - * for i in range(dst_extent): - * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<< - * src_data += src_stride - * dst_data += dst_stride - */ - (void)(memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize)); - - /* "View.MemoryView":1159 - * for i in range(dst_extent): - * memcpy(dst_data, src_data, itemsize) - * src_data += src_stride # <<<<<<<<<<<<<< - * dst_data += dst_stride - * else: - */ - __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride); - - /* "View.MemoryView":1160 - * memcpy(dst_data, src_data, itemsize) - * src_data += src_stride - * dst_data += dst_stride # <<<<<<<<<<<<<< - * else: - * for i in range(dst_extent): - */ - __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride); - } - } - __pyx_L4:; - - /* "View.MemoryView":1152 - * cdef Py_ssize_t dst_stride = dst_strides[0] - * - * if ndim == 1: # <<<<<<<<<<<<<< - * if (src_stride > 0 and dst_stride > 0 and - * src_stride == itemsize == dst_stride): - */ - goto __pyx_L3; - } - - /* "View.MemoryView":1162 - * dst_data += dst_stride - * else: - * for i in range(dst_extent): # <<<<<<<<<<<<<< - * _copy_strided_to_strided(src_data, src_strides + 1, - * dst_data, dst_strides + 1, - */ - /*else*/ { - __pyx_t_4 = __pyx_v_dst_extent; - __pyx_t_5 = __pyx_t_4; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; - - /* "View.MemoryView":1163 - * else: - * for i in range(dst_extent): - * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<< - * dst_data, dst_strides + 1, - * src_shape + 1, dst_shape + 1, - */ - _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize); - - /* "View.MemoryView":1167 - * src_shape + 1, dst_shape + 1, - * ndim - 1, itemsize) - * src_data += src_stride # <<<<<<<<<<<<<< - * dst_data += dst_stride - * - */ - __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride); - - /* "View.MemoryView":1168 - * ndim - 1, itemsize) - * src_data += src_stride - * dst_data += dst_stride # <<<<<<<<<<<<<< - * - * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, - */ - __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride); - } - } - __pyx_L3:; - - /* "View.MemoryView":1140 - * - * @cython.cdivision(True) - * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<< - * char *dst_data, Py_ssize_t *dst_strides, - * Py_ssize_t *src_shape, Py_ssize_t *dst_shape, - */ - - /* function exit code */ -} - -/* "View.MemoryView":1170 - * dst_data += dst_stride - * - * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *dst, - * int ndim, size_t itemsize) nogil: - */ - -static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) { - - /* "View.MemoryView":1173 - * __Pyx_memviewslice *dst, - * int ndim, size_t itemsize) nogil: - * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<< - * src.shape, dst.shape, ndim, itemsize) - * - */ - _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize); - - /* "View.MemoryView":1170 - * dst_data += dst_stride - * - * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *dst, - * int ndim, size_t itemsize) nogil: - */ - - /* function exit code */ -} - -/* "View.MemoryView":1177 - * - * @cname('__pyx_memoryview_slice_get_size') - * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<< - * "Return the size of the memory occupied by the slice in number of bytes" - * cdef Py_ssize_t shape, size = src.memview.view.itemsize - */ - -static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) { - Py_ssize_t __pyx_v_shape; - Py_ssize_t __pyx_v_size; - Py_ssize_t __pyx_r; - Py_ssize_t __pyx_t_1; - Py_ssize_t *__pyx_t_2; - Py_ssize_t *__pyx_t_3; - Py_ssize_t *__pyx_t_4; - - /* "View.MemoryView":1179 - * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: - * "Return the size of the memory occupied by the slice in number of bytes" - * cdef Py_ssize_t shape, size = src.memview.view.itemsize # <<<<<<<<<<<<<< - * - * for shape in src.shape[:ndim]: - */ - __pyx_t_1 = __pyx_v_src->memview->view.itemsize; - __pyx_v_size = __pyx_t_1; - - /* "View.MemoryView":1181 - * cdef Py_ssize_t shape, size = src.memview.view.itemsize - * - * for shape in src.shape[:ndim]: # <<<<<<<<<<<<<< - * size *= shape - * - */ - __pyx_t_3 = (__pyx_v_src->shape + __pyx_v_ndim); - for (__pyx_t_4 = __pyx_v_src->shape; __pyx_t_4 < __pyx_t_3; __pyx_t_4++) { - __pyx_t_2 = __pyx_t_4; - __pyx_v_shape = (__pyx_t_2[0]); - - /* "View.MemoryView":1182 - * - * for shape in src.shape[:ndim]: - * size *= shape # <<<<<<<<<<<<<< - * - * return size - */ - __pyx_v_size = (__pyx_v_size * __pyx_v_shape); - } - - /* "View.MemoryView":1184 - * size *= shape - * - * return size # <<<<<<<<<<<<<< - * - * @cname('__pyx_fill_contig_strides_array') - */ - __pyx_r = __pyx_v_size; - goto __pyx_L0; - - /* "View.MemoryView":1177 - * - * @cname('__pyx_memoryview_slice_get_size') - * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<< - * "Return the size of the memory occupied by the slice in number of bytes" - * cdef Py_ssize_t shape, size = src.memview.view.itemsize - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1187 - * - * @cname('__pyx_fill_contig_strides_array') - * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<< - * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride, - * int ndim, char order) nogil: - */ - -static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) { - int __pyx_v_idx; - Py_ssize_t __pyx_r; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - - /* "View.MemoryView":1196 - * cdef int idx - * - * if order == 'F': # <<<<<<<<<<<<<< - * for idx in range(ndim): - * strides[idx] = stride - */ - __pyx_t_1 = ((__pyx_v_order == 'F') != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":1197 - * - * if order == 'F': - * for idx in range(ndim): # <<<<<<<<<<<<<< - * strides[idx] = stride - * stride *= shape[idx] - */ - __pyx_t_2 = __pyx_v_ndim; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_idx = __pyx_t_4; - - /* "View.MemoryView":1198 - * if order == 'F': - * for idx in range(ndim): - * strides[idx] = stride # <<<<<<<<<<<<<< - * stride *= shape[idx] - * else: - */ - (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride; - - /* "View.MemoryView":1199 - * for idx in range(ndim): - * strides[idx] = stride - * stride *= shape[idx] # <<<<<<<<<<<<<< - * else: - * for idx in range(ndim - 1, -1, -1): - */ - __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx])); - } - - /* "View.MemoryView":1196 - * cdef int idx - * - * if order == 'F': # <<<<<<<<<<<<<< - * for idx in range(ndim): - * strides[idx] = stride - */ - goto __pyx_L3; - } - - /* "View.MemoryView":1201 - * stride *= shape[idx] - * else: - * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< - * strides[idx] = stride - * stride *= shape[idx] - */ - /*else*/ { - for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) { - __pyx_v_idx = __pyx_t_2; - - /* "View.MemoryView":1202 - * else: - * for idx in range(ndim - 1, -1, -1): - * strides[idx] = stride # <<<<<<<<<<<<<< - * stride *= shape[idx] - * - */ - (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride; - - /* "View.MemoryView":1203 - * for idx in range(ndim - 1, -1, -1): - * strides[idx] = stride - * stride *= shape[idx] # <<<<<<<<<<<<<< - * - * return stride - */ - __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx])); - } - } - __pyx_L3:; - - /* "View.MemoryView":1205 - * stride *= shape[idx] - * - * return stride # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_copy_data_to_temp') - */ - __pyx_r = __pyx_v_stride; - goto __pyx_L0; - - /* "View.MemoryView":1187 - * - * @cname('__pyx_fill_contig_strides_array') - * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<< - * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride, - * int ndim, char order) nogil: - */ - - /* function exit code */ - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1208 - * - * @cname('__pyx_memoryview_copy_data_to_temp') - * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *tmpslice, - * char order, - */ - -static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) { - int __pyx_v_i; - void *__pyx_v_result; - size_t __pyx_v_itemsize; - size_t __pyx_v_size; - void *__pyx_r; - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - struct __pyx_memoryview_obj *__pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - - /* "View.MemoryView":1219 - * cdef void *result - * - * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<< - * cdef size_t size = slice_get_size(src, ndim) - * - */ - __pyx_t_1 = __pyx_v_src->memview->view.itemsize; - __pyx_v_itemsize = __pyx_t_1; - - /* "View.MemoryView":1220 - * - * cdef size_t itemsize = src.memview.view.itemsize - * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<< - * - * result = malloc(size) - */ - __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim); - - /* "View.MemoryView":1222 - * cdef size_t size = slice_get_size(src, ndim) - * - * result = malloc(size) # <<<<<<<<<<<<<< - * if not result: - * _err(MemoryError, NULL) - */ - __pyx_v_result = malloc(__pyx_v_size); - - /* "View.MemoryView":1223 - * - * result = malloc(size) - * if not result: # <<<<<<<<<<<<<< - * _err(MemoryError, NULL) - * - */ - __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1224 - * result = malloc(size) - * if not result: - * _err(MemoryError, NULL) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(2, 1224, __pyx_L1_error) - - /* "View.MemoryView":1223 - * - * result = malloc(size) - * if not result: # <<<<<<<<<<<<<< - * _err(MemoryError, NULL) - * - */ - } - - /* "View.MemoryView":1227 - * - * - * tmpslice.data = result # <<<<<<<<<<<<<< - * tmpslice.memview = src.memview - * for i in range(ndim): - */ - __pyx_v_tmpslice->data = ((char *)__pyx_v_result); - - /* "View.MemoryView":1228 - * - * tmpslice.data = result - * tmpslice.memview = src.memview # <<<<<<<<<<<<<< - * for i in range(ndim): - * tmpslice.shape[i] = src.shape[i] - */ - __pyx_t_4 = __pyx_v_src->memview; - __pyx_v_tmpslice->memview = __pyx_t_4; - - /* "View.MemoryView":1229 - * tmpslice.data = result - * tmpslice.memview = src.memview - * for i in range(ndim): # <<<<<<<<<<<<<< - * tmpslice.shape[i] = src.shape[i] - * tmpslice.suboffsets[i] = -1 - */ - __pyx_t_3 = __pyx_v_ndim; - __pyx_t_5 = __pyx_t_3; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; - - /* "View.MemoryView":1230 - * tmpslice.memview = src.memview - * for i in range(ndim): - * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<< - * tmpslice.suboffsets[i] = -1 - * - */ - (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]); - - /* "View.MemoryView":1231 - * for i in range(ndim): - * tmpslice.shape[i] = src.shape[i] - * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<< - * - * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, - */ - (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1L; - } - - /* "View.MemoryView":1233 - * tmpslice.suboffsets[i] = -1 - * - * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<< - * ndim, order) - * - */ - (void)(__pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order)); - - /* "View.MemoryView":1237 - * - * - * for i in range(ndim): # <<<<<<<<<<<<<< - * if tmpslice.shape[i] == 1: - * tmpslice.strides[i] = 0 - */ - __pyx_t_3 = __pyx_v_ndim; - __pyx_t_5 = __pyx_t_3; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; - - /* "View.MemoryView":1238 - * - * for i in range(ndim): - * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<< - * tmpslice.strides[i] = 0 - * - */ - __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1239 - * for i in range(ndim): - * if tmpslice.shape[i] == 1: - * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<< - * - * if slice_is_contig(src[0], order, ndim): - */ - (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0; - - /* "View.MemoryView":1238 - * - * for i in range(ndim): - * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<< - * tmpslice.strides[i] = 0 - * - */ - } - } - - /* "View.MemoryView":1241 - * tmpslice.strides[i] = 0 - * - * if slice_is_contig(src[0], order, ndim): # <<<<<<<<<<<<<< - * memcpy(result, src.data, size) - * else: - */ - __pyx_t_2 = (__pyx_memviewslice_is_contig((__pyx_v_src[0]), __pyx_v_order, __pyx_v_ndim) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1242 - * - * if slice_is_contig(src[0], order, ndim): - * memcpy(result, src.data, size) # <<<<<<<<<<<<<< - * else: - * copy_strided_to_strided(src, tmpslice, ndim, itemsize) - */ - (void)(memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size)); - - /* "View.MemoryView":1241 - * tmpslice.strides[i] = 0 - * - * if slice_is_contig(src[0], order, ndim): # <<<<<<<<<<<<<< - * memcpy(result, src.data, size) - * else: - */ - goto __pyx_L9; - } - - /* "View.MemoryView":1244 - * memcpy(result, src.data, size) - * else: - * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<< - * - * return result - */ - /*else*/ { - copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize); - } - __pyx_L9:; - - /* "View.MemoryView":1246 - * copy_strided_to_strided(src, tmpslice, ndim, itemsize) - * - * return result # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_result; - goto __pyx_L0; - - /* "View.MemoryView":1208 - * - * @cname('__pyx_memoryview_copy_data_to_temp') - * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice *tmpslice, - * char order, - */ - - /* function exit code */ - __pyx_L1_error:; - { - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - } - __pyx_r = NULL; - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1251 - * - * @cname('__pyx_memoryview_err_extents') - * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<< - * Py_ssize_t extent2) except -1 with gil: - * raise ValueError("got differing extents in dimension %d (got %d and %d)" % - */ - -static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_RefNannySetupContext("_err_extents", 0); - - /* "View.MemoryView":1254 - * Py_ssize_t extent2) except -1 with gil: - * raise ValueError("got differing extents in dimension %d (got %d and %d)" % - * (i, extent1, extent2)) # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_err_dim') - */ - __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 1254, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1254, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1254, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 1254, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_t_3 = 0; - - /* "View.MemoryView":1253 - * cdef int _err_extents(int i, Py_ssize_t extent1, - * Py_ssize_t extent2) except -1 with gil: - * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<< - * (i, extent1, extent2)) - * - */ - __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1253, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 1253, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_4, 0, 0, 0); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __PYX_ERR(2, 1253, __pyx_L1_error) - - /* "View.MemoryView":1251 - * - * @cname('__pyx_memoryview_err_extents') - * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<< - * Py_ssize_t extent2) except -1 with gil: - * raise ValueError("got differing extents in dimension %d (got %d and %d)" % - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __Pyx_RefNannyFinishContext(); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - return __pyx_r; -} - -/* "View.MemoryView":1257 - * - * @cname('__pyx_memoryview_err_dim') - * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<< - * raise error(msg.decode('ascii') % dim) - * - */ - -static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_RefNannySetupContext("_err_dim", 0); - __Pyx_INCREF(__pyx_v_error); - - /* "View.MemoryView":1258 - * @cname('__pyx_memoryview_err_dim') - * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: - * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_err') - */ - __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1258, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1258, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 1258, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_INCREF(__pyx_v_error); - __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_2)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_2); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - } - } - __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_2, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 1258, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 1258, __pyx_L1_error) - - /* "View.MemoryView":1257 - * - * @cname('__pyx_memoryview_err_dim') - * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<< - * raise error(msg.decode('ascii') % dim) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __Pyx_XDECREF(__pyx_v_error); - __Pyx_RefNannyFinishContext(); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - return __pyx_r; -} - -/* "View.MemoryView":1261 - * - * @cname('__pyx_memoryview_err') - * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<< - * if msg != NULL: - * raise error(msg.decode('ascii')) - */ - -static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_RefNannySetupContext("_err", 0); - __Pyx_INCREF(__pyx_v_error); - - /* "View.MemoryView":1262 - * @cname('__pyx_memoryview_err') - * cdef int _err(object error, char *msg) except -1 with gil: - * if msg != NULL: # <<<<<<<<<<<<<< - * raise error(msg.decode('ascii')) - * else: - */ - __pyx_t_1 = ((__pyx_v_msg != NULL) != 0); - if (unlikely(__pyx_t_1)) { - - /* "View.MemoryView":1263 - * cdef int _err(object error, char *msg) except -1 with gil: - * if msg != NULL: - * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<< - * else: - * raise error - */ - __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1263, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_v_error); - __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - } - } - __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1263, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(2, 1263, __pyx_L1_error) - - /* "View.MemoryView":1262 - * @cname('__pyx_memoryview_err') - * cdef int _err(object error, char *msg) except -1 with gil: - * if msg != NULL: # <<<<<<<<<<<<<< - * raise error(msg.decode('ascii')) - * else: - */ - } - - /* "View.MemoryView":1265 - * raise error(msg.decode('ascii')) - * else: - * raise error # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_copy_contents') - */ - /*else*/ { - __Pyx_Raise(__pyx_v_error, 0, 0, 0); - __PYX_ERR(2, 1265, __pyx_L1_error) - } - - /* "View.MemoryView":1261 - * - * @cname('__pyx_memoryview_err') - * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<< - * if msg != NULL: - * raise error(msg.decode('ascii')) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __Pyx_XDECREF(__pyx_v_error); - __Pyx_RefNannyFinishContext(); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - return __pyx_r; -} - -/* "View.MemoryView":1268 - * - * @cname('__pyx_memoryview_copy_contents') - * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice dst, - * int src_ndim, int dst_ndim, - */ - -static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) { - void *__pyx_v_tmpdata; - size_t __pyx_v_itemsize; - int __pyx_v_i; - char __pyx_v_order; - int __pyx_v_broadcasting; - int __pyx_v_direct_copy; - __Pyx_memviewslice __pyx_v_tmp; - int __pyx_v_ndim; - int __pyx_r; - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - int __pyx_t_6; - void *__pyx_t_7; - int __pyx_t_8; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - - /* "View.MemoryView":1276 - * Check for overlapping memory and verify the shapes. - * """ - * cdef void *tmpdata = NULL # <<<<<<<<<<<<<< - * cdef size_t itemsize = src.memview.view.itemsize - * cdef int i - */ - __pyx_v_tmpdata = NULL; - - /* "View.MemoryView":1277 - * """ - * cdef void *tmpdata = NULL - * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<< - * cdef int i - * cdef char order = get_best_order(&src, src_ndim) - */ - __pyx_t_1 = __pyx_v_src.memview->view.itemsize; - __pyx_v_itemsize = __pyx_t_1; - - /* "View.MemoryView":1279 - * cdef size_t itemsize = src.memview.view.itemsize - * cdef int i - * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<< - * cdef bint broadcasting = False - * cdef bint direct_copy = False - */ - __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim); - - /* "View.MemoryView":1280 - * cdef int i - * cdef char order = get_best_order(&src, src_ndim) - * cdef bint broadcasting = False # <<<<<<<<<<<<<< - * cdef bint direct_copy = False - * cdef __Pyx_memviewslice tmp - */ - __pyx_v_broadcasting = 0; - - /* "View.MemoryView":1281 - * cdef char order = get_best_order(&src, src_ndim) - * cdef bint broadcasting = False - * cdef bint direct_copy = False # <<<<<<<<<<<<<< - * cdef __Pyx_memviewslice tmp - * - */ - __pyx_v_direct_copy = 0; - - /* "View.MemoryView":1284 - * cdef __Pyx_memviewslice tmp - * - * if src_ndim < dst_ndim: # <<<<<<<<<<<<<< - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: - */ - __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1285 - * - * if src_ndim < dst_ndim: - * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<< - * elif dst_ndim < src_ndim: - * broadcast_leading(&dst, dst_ndim, src_ndim) - */ - __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim); - - /* "View.MemoryView":1284 - * cdef __Pyx_memviewslice tmp - * - * if src_ndim < dst_ndim: # <<<<<<<<<<<<<< - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: - */ - goto __pyx_L3; - } - - /* "View.MemoryView":1286 - * if src_ndim < dst_ndim: - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<< - * broadcast_leading(&dst, dst_ndim, src_ndim) - * - */ - __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1287 - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: - * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<< - * - * cdef int ndim = max(src_ndim, dst_ndim) - */ - __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim); - - /* "View.MemoryView":1286 - * if src_ndim < dst_ndim: - * broadcast_leading(&src, src_ndim, dst_ndim) - * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<< - * broadcast_leading(&dst, dst_ndim, src_ndim) - * - */ - } - __pyx_L3:; - - /* "View.MemoryView":1289 - * broadcast_leading(&dst, dst_ndim, src_ndim) - * - * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<< - * - * for i in range(ndim): - */ - __pyx_t_3 = __pyx_v_dst_ndim; - __pyx_t_4 = __pyx_v_src_ndim; - if (((__pyx_t_3 > __pyx_t_4) != 0)) { - __pyx_t_5 = __pyx_t_3; - } else { - __pyx_t_5 = __pyx_t_4; - } - __pyx_v_ndim = __pyx_t_5; - - /* "View.MemoryView":1291 - * cdef int ndim = max(src_ndim, dst_ndim) - * - * for i in range(ndim): # <<<<<<<<<<<<<< - * if src.shape[i] != dst.shape[i]: - * if src.shape[i] == 1: - */ - __pyx_t_5 = __pyx_v_ndim; - __pyx_t_3 = __pyx_t_5; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; - - /* "View.MemoryView":1292 - * - * for i in range(ndim): - * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<< - * if src.shape[i] == 1: - * broadcasting = True - */ - __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1293 - * for i in range(ndim): - * if src.shape[i] != dst.shape[i]: - * if src.shape[i] == 1: # <<<<<<<<<<<<<< - * broadcasting = True - * src.strides[i] = 0 - */ - __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1294 - * if src.shape[i] != dst.shape[i]: - * if src.shape[i] == 1: - * broadcasting = True # <<<<<<<<<<<<<< - * src.strides[i] = 0 - * else: - */ - __pyx_v_broadcasting = 1; - - /* "View.MemoryView":1295 - * if src.shape[i] == 1: - * broadcasting = True - * src.strides[i] = 0 # <<<<<<<<<<<<<< - * else: - * _err_extents(i, dst.shape[i], src.shape[i]) - */ - (__pyx_v_src.strides[__pyx_v_i]) = 0; - - /* "View.MemoryView":1293 - * for i in range(ndim): - * if src.shape[i] != dst.shape[i]: - * if src.shape[i] == 1: # <<<<<<<<<<<<<< - * broadcasting = True - * src.strides[i] = 0 - */ - goto __pyx_L7; - } - - /* "View.MemoryView":1297 - * src.strides[i] = 0 - * else: - * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<< - * - * if src.suboffsets[i] >= 0: - */ - /*else*/ { - __pyx_t_6 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(2, 1297, __pyx_L1_error) - } - __pyx_L7:; - - /* "View.MemoryView":1292 - * - * for i in range(ndim): - * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<< - * if src.shape[i] == 1: - * broadcasting = True - */ - } - - /* "View.MemoryView":1299 - * _err_extents(i, dst.shape[i], src.shape[i]) - * - * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<< - * _err_dim(ValueError, "Dimension %d is not direct", i) - * - */ - __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1300 - * - * if src.suboffsets[i] >= 0: - * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<< - * - * if slices_overlap(&src, &dst, ndim, itemsize): - */ - __pyx_t_6 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, ((char *)"Dimension %d is not direct"), __pyx_v_i); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(2, 1300, __pyx_L1_error) - - /* "View.MemoryView":1299 - * _err_extents(i, dst.shape[i], src.shape[i]) - * - * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<< - * _err_dim(ValueError, "Dimension %d is not direct", i) - * - */ - } - } - - /* "View.MemoryView":1302 - * _err_dim(ValueError, "Dimension %d is not direct", i) - * - * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<< - * - * if not slice_is_contig(src, order, ndim): - */ - __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1304 - * if slices_overlap(&src, &dst, ndim, itemsize): - * - * if not slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<< - * order = get_best_order(&dst, ndim) - * - */ - __pyx_t_2 = ((!(__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1305 - * - * if not slice_is_contig(src, order, ndim): - * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<< - * - * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) - */ - __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim); - - /* "View.MemoryView":1304 - * if slices_overlap(&src, &dst, ndim, itemsize): - * - * if not slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<< - * order = get_best_order(&dst, ndim) - * - */ - } - - /* "View.MemoryView":1307 - * order = get_best_order(&dst, ndim) - * - * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<< - * src = tmp - * - */ - __pyx_t_7 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_7 == ((void *)NULL))) __PYX_ERR(2, 1307, __pyx_L1_error) - __pyx_v_tmpdata = __pyx_t_7; - - /* "View.MemoryView":1308 - * - * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) - * src = tmp # <<<<<<<<<<<<<< - * - * if not broadcasting: - */ - __pyx_v_src = __pyx_v_tmp; - - /* "View.MemoryView":1302 - * _err_dim(ValueError, "Dimension %d is not direct", i) - * - * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<< - * - * if not slice_is_contig(src, order, ndim): - */ - } - - /* "View.MemoryView":1310 - * src = tmp - * - * if not broadcasting: # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1313 - * - * - * if slice_is_contig(src, 'C', ndim): # <<<<<<<<<<<<<< - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): - */ - __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, 'C', __pyx_v_ndim) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1314 - * - * if slice_is_contig(src, 'C', ndim): - * direct_copy = slice_is_contig(dst, 'C', ndim) # <<<<<<<<<<<<<< - * elif slice_is_contig(src, 'F', ndim): - * direct_copy = slice_is_contig(dst, 'F', ndim) - */ - __pyx_v_direct_copy = __pyx_memviewslice_is_contig(__pyx_v_dst, 'C', __pyx_v_ndim); - - /* "View.MemoryView":1313 - * - * - * if slice_is_contig(src, 'C', ndim): # <<<<<<<<<<<<<< - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): - */ - goto __pyx_L12; - } - - /* "View.MemoryView":1315 - * if slice_is_contig(src, 'C', ndim): - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): # <<<<<<<<<<<<<< - * direct_copy = slice_is_contig(dst, 'F', ndim) - * - */ - __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, 'F', __pyx_v_ndim) != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1316 - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): - * direct_copy = slice_is_contig(dst, 'F', ndim) # <<<<<<<<<<<<<< - * - * if direct_copy: - */ - __pyx_v_direct_copy = __pyx_memviewslice_is_contig(__pyx_v_dst, 'F', __pyx_v_ndim); - - /* "View.MemoryView":1315 - * if slice_is_contig(src, 'C', ndim): - * direct_copy = slice_is_contig(dst, 'C', ndim) - * elif slice_is_contig(src, 'F', ndim): # <<<<<<<<<<<<<< - * direct_copy = slice_is_contig(dst, 'F', ndim) - * - */ - } - __pyx_L12:; - - /* "View.MemoryView":1318 - * direct_copy = slice_is_contig(dst, 'F', ndim) - * - * if direct_copy: # <<<<<<<<<<<<<< - * - * refcount_copying(&dst, dtype_is_object, ndim, False) - */ - __pyx_t_2 = (__pyx_v_direct_copy != 0); - if (__pyx_t_2) { - - /* "View.MemoryView":1320 - * if direct_copy: - * - * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<< - * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) - * refcount_copying(&dst, dtype_is_object, ndim, True) - */ - __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0); - - /* "View.MemoryView":1321 - * - * refcount_copying(&dst, dtype_is_object, ndim, False) - * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<< - * refcount_copying(&dst, dtype_is_object, ndim, True) - * free(tmpdata) - */ - (void)(memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim))); - - /* "View.MemoryView":1322 - * refcount_copying(&dst, dtype_is_object, ndim, False) - * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) - * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<< - * free(tmpdata) - * return 0 - */ - __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1); - - /* "View.MemoryView":1323 - * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) - * refcount_copying(&dst, dtype_is_object, ndim, True) - * free(tmpdata) # <<<<<<<<<<<<<< - * return 0 - * - */ - free(__pyx_v_tmpdata); - - /* "View.MemoryView":1324 - * refcount_copying(&dst, dtype_is_object, ndim, True) - * free(tmpdata) - * return 0 # <<<<<<<<<<<<<< - * - * if order == 'F' == get_best_order(&dst, ndim): - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "View.MemoryView":1318 - * direct_copy = slice_is_contig(dst, 'F', ndim) - * - * if direct_copy: # <<<<<<<<<<<<<< - * - * refcount_copying(&dst, dtype_is_object, ndim, False) - */ - } - - /* "View.MemoryView":1310 - * src = tmp - * - * if not broadcasting: # <<<<<<<<<<<<<< - * - * - */ - } - - /* "View.MemoryView":1326 - * return 0 - * - * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_2 = (__pyx_v_order == 'F'); - if (__pyx_t_2) { - __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim)); - } - __pyx_t_8 = (__pyx_t_2 != 0); - if (__pyx_t_8) { - - /* "View.MemoryView":1329 - * - * - * transpose_memslice(&src) # <<<<<<<<<<<<<< - * transpose_memslice(&dst) - * - */ - __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(2, 1329, __pyx_L1_error) - - /* "View.MemoryView":1330 - * - * transpose_memslice(&src) - * transpose_memslice(&dst) # <<<<<<<<<<<<<< - * - * refcount_copying(&dst, dtype_is_object, ndim, False) - */ - __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(2, 1330, __pyx_L1_error) - - /* "View.MemoryView":1326 - * return 0 - * - * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<< - * - * - */ - } - - /* "View.MemoryView":1332 - * transpose_memslice(&dst) - * - * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<< - * copy_strided_to_strided(&src, &dst, ndim, itemsize) - * refcount_copying(&dst, dtype_is_object, ndim, True) - */ - __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0); - - /* "View.MemoryView":1333 - * - * refcount_copying(&dst, dtype_is_object, ndim, False) - * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<< - * refcount_copying(&dst, dtype_is_object, ndim, True) - * - */ - copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize); - - /* "View.MemoryView":1334 - * refcount_copying(&dst, dtype_is_object, ndim, False) - * copy_strided_to_strided(&src, &dst, ndim, itemsize) - * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<< - * - * free(tmpdata) - */ - __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1); - - /* "View.MemoryView":1336 - * refcount_copying(&dst, dtype_is_object, ndim, True) - * - * free(tmpdata) # <<<<<<<<<<<<<< - * return 0 - * - */ - free(__pyx_v_tmpdata); - - /* "View.MemoryView":1337 - * - * free(tmpdata) - * return 0 # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_broadcast_leading') - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "View.MemoryView":1268 - * - * @cname('__pyx_memoryview_copy_contents') - * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<< - * __Pyx_memviewslice dst, - * int src_ndim, int dst_ndim, - */ - - /* function exit code */ - __pyx_L1_error:; - { - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif - } - __pyx_r = -1; - __pyx_L0:; - return __pyx_r; -} - -/* "View.MemoryView":1340 - * - * @cname('__pyx_memoryview_broadcast_leading') - * cdef void broadcast_leading(__Pyx_memviewslice *mslice, # <<<<<<<<<<<<<< - * int ndim, - * int ndim_other) nogil: - */ - -static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim, int __pyx_v_ndim_other) { - int __pyx_v_i; - int __pyx_v_offset; - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - - /* "View.MemoryView":1344 - * int ndim_other) nogil: - * cdef int i - * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<< - * - * for i in range(ndim - 1, -1, -1): - */ - __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim); - - /* "View.MemoryView":1346 - * cdef int offset = ndim_other - ndim - * - * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< - * mslice.shape[i + offset] = mslice.shape[i] - * mslice.strides[i + offset] = mslice.strides[i] - */ - for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) { - __pyx_v_i = __pyx_t_1; - - /* "View.MemoryView":1347 - * - * for i in range(ndim - 1, -1, -1): - * mslice.shape[i + offset] = mslice.shape[i] # <<<<<<<<<<<<<< - * mslice.strides[i + offset] = mslice.strides[i] - * mslice.suboffsets[i + offset] = mslice.suboffsets[i] - */ - (__pyx_v_mslice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->shape[__pyx_v_i]); - - /* "View.MemoryView":1348 - * for i in range(ndim - 1, -1, -1): - * mslice.shape[i + offset] = mslice.shape[i] - * mslice.strides[i + offset] = mslice.strides[i] # <<<<<<<<<<<<<< - * mslice.suboffsets[i + offset] = mslice.suboffsets[i] - * - */ - (__pyx_v_mslice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->strides[__pyx_v_i]); - - /* "View.MemoryView":1349 - * mslice.shape[i + offset] = mslice.shape[i] - * mslice.strides[i + offset] = mslice.strides[i] - * mslice.suboffsets[i + offset] = mslice.suboffsets[i] # <<<<<<<<<<<<<< - * - * for i in range(offset): - */ - (__pyx_v_mslice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->suboffsets[__pyx_v_i]); - } - - /* "View.MemoryView":1351 - * mslice.suboffsets[i + offset] = mslice.suboffsets[i] - * - * for i in range(offset): # <<<<<<<<<<<<<< - * mslice.shape[i] = 1 - * mslice.strides[i] = mslice.strides[0] - */ - __pyx_t_1 = __pyx_v_offset; - __pyx_t_2 = __pyx_t_1; - for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { - __pyx_v_i = __pyx_t_3; - - /* "View.MemoryView":1352 - * - * for i in range(offset): - * mslice.shape[i] = 1 # <<<<<<<<<<<<<< - * mslice.strides[i] = mslice.strides[0] - * mslice.suboffsets[i] = -1 - */ - (__pyx_v_mslice->shape[__pyx_v_i]) = 1; - - /* "View.MemoryView":1353 - * for i in range(offset): - * mslice.shape[i] = 1 - * mslice.strides[i] = mslice.strides[0] # <<<<<<<<<<<<<< - * mslice.suboffsets[i] = -1 - * - */ - (__pyx_v_mslice->strides[__pyx_v_i]) = (__pyx_v_mslice->strides[0]); - - /* "View.MemoryView":1354 - * mslice.shape[i] = 1 - * mslice.strides[i] = mslice.strides[0] - * mslice.suboffsets[i] = -1 # <<<<<<<<<<<<<< - * - * - */ - (__pyx_v_mslice->suboffsets[__pyx_v_i]) = -1L; - } - - /* "View.MemoryView":1340 - * - * @cname('__pyx_memoryview_broadcast_leading') - * cdef void broadcast_leading(__Pyx_memviewslice *mslice, # <<<<<<<<<<<<<< - * int ndim, - * int ndim_other) nogil: - */ - - /* function exit code */ -} - -/* "View.MemoryView":1362 - * - * @cname('__pyx_memoryview_refcount_copying') - * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<< - * int ndim, bint inc) nogil: - * - */ - -static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) { - int __pyx_t_1; - - /* "View.MemoryView":1366 - * - * - * if dtype_is_object: # <<<<<<<<<<<<<< - * refcount_objects_in_slice_with_gil(dst.data, dst.shape, - * dst.strides, ndim, inc) - */ - __pyx_t_1 = (__pyx_v_dtype_is_object != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":1367 - * - * if dtype_is_object: - * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<< - * dst.strides, ndim, inc) - * - */ - __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc); - - /* "View.MemoryView":1366 - * - * - * if dtype_is_object: # <<<<<<<<<<<<<< - * refcount_objects_in_slice_with_gil(dst.data, dst.shape, - * dst.strides, ndim, inc) - */ - } - - /* "View.MemoryView":1362 - * - * @cname('__pyx_memoryview_refcount_copying') - * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<< - * int ndim, bint inc) nogil: - * - */ - - /* function exit code */ -} - -/* "View.MemoryView":1371 - * - * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') - * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, - * bint inc) with gil: - */ - -static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) { - __Pyx_RefNannyDeclarations - #ifdef WITH_THREAD - PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); - #endif - __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0); - - /* "View.MemoryView":1374 - * Py_ssize_t *strides, int ndim, - * bint inc) with gil: - * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<< - * - * @cname('__pyx_memoryview_refcount_objects_in_slice') - */ - __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc); - - /* "View.MemoryView":1371 - * - * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') - * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, - * bint inc) with gil: - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - #ifdef WITH_THREAD - __Pyx_PyGILState_Release(__pyx_gilstate_save); - #endif -} - -/* "View.MemoryView":1377 - * - * @cname('__pyx_memoryview_refcount_objects_in_slice') - * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, bint inc): - * cdef Py_ssize_t i - */ - -static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) { - CYTHON_UNUSED Py_ssize_t __pyx_v_i; - __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; - Py_ssize_t __pyx_t_2; - Py_ssize_t __pyx_t_3; - int __pyx_t_4; - __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0); - - /* "View.MemoryView":1381 - * cdef Py_ssize_t i - * - * for i in range(shape[0]): # <<<<<<<<<<<<<< - * if ndim == 1: - * if inc: - */ - __pyx_t_1 = (__pyx_v_shape[0]); - __pyx_t_2 = __pyx_t_1; - for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { - __pyx_v_i = __pyx_t_3; - - /* "View.MemoryView":1382 - * - * for i in range(shape[0]): - * if ndim == 1: # <<<<<<<<<<<<<< - * if inc: - * Py_INCREF(( data)[0]) - */ - __pyx_t_4 = ((__pyx_v_ndim == 1) != 0); - if (__pyx_t_4) { - - /* "View.MemoryView":1383 - * for i in range(shape[0]): - * if ndim == 1: - * if inc: # <<<<<<<<<<<<<< - * Py_INCREF(( data)[0]) - * else: - */ - __pyx_t_4 = (__pyx_v_inc != 0); - if (__pyx_t_4) { - - /* "View.MemoryView":1384 - * if ndim == 1: - * if inc: - * Py_INCREF(( data)[0]) # <<<<<<<<<<<<<< - * else: - * Py_DECREF(( data)[0]) - */ - Py_INCREF((((PyObject **)__pyx_v_data)[0])); - - /* "View.MemoryView":1383 - * for i in range(shape[0]): - * if ndim == 1: - * if inc: # <<<<<<<<<<<<<< - * Py_INCREF(( data)[0]) - * else: - */ - goto __pyx_L6; - } - - /* "View.MemoryView":1386 - * Py_INCREF(( data)[0]) - * else: - * Py_DECREF(( data)[0]) # <<<<<<<<<<<<<< - * else: - * refcount_objects_in_slice(data, shape + 1, strides + 1, - */ - /*else*/ { - Py_DECREF((((PyObject **)__pyx_v_data)[0])); - } - __pyx_L6:; - - /* "View.MemoryView":1382 - * - * for i in range(shape[0]): - * if ndim == 1: # <<<<<<<<<<<<<< - * if inc: - * Py_INCREF(( data)[0]) - */ - goto __pyx_L5; - } - - /* "View.MemoryView":1388 - * Py_DECREF(( data)[0]) - * else: - * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<< - * ndim - 1, inc) - * - */ - /*else*/ { - - /* "View.MemoryView":1389 - * else: - * refcount_objects_in_slice(data, shape + 1, strides + 1, - * ndim - 1, inc) # <<<<<<<<<<<<<< - * - * data += strides[0] - */ - __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc); - } - __pyx_L5:; - - /* "View.MemoryView":1391 - * ndim - 1, inc) - * - * data += strides[0] # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0])); - } - - /* "View.MemoryView":1377 - * - * @cname('__pyx_memoryview_refcount_objects_in_slice') - * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, bint inc): - * cdef Py_ssize_t i - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "View.MemoryView":1397 - * - * @cname('__pyx_memoryview_slice_assign_scalar') - * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<< - * size_t itemsize, void *item, - * bint dtype_is_object) nogil: - */ - -static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) { - - /* "View.MemoryView":1400 - * size_t itemsize, void *item, - * bint dtype_is_object) nogil: - * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<< - * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, - * itemsize, item) - */ - __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0); - - /* "View.MemoryView":1401 - * bint dtype_is_object) nogil: - * refcount_copying(dst, dtype_is_object, ndim, False) - * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<< - * itemsize, item) - * refcount_copying(dst, dtype_is_object, ndim, True) - */ - __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item); - - /* "View.MemoryView":1403 - * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, - * itemsize, item) - * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<< - * - * - */ - __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1); - - /* "View.MemoryView":1397 - * - * @cname('__pyx_memoryview_slice_assign_scalar') - * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<< - * size_t itemsize, void *item, - * bint dtype_is_object) nogil: - */ - - /* function exit code */ -} - -/* "View.MemoryView":1407 - * - * @cname('__pyx_memoryview__slice_assign_scalar') - * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, - * size_t itemsize, void *item) nogil: - */ - -static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) { - CYTHON_UNUSED Py_ssize_t __pyx_v_i; - Py_ssize_t __pyx_v_stride; - Py_ssize_t __pyx_v_extent; - int __pyx_t_1; - Py_ssize_t __pyx_t_2; - Py_ssize_t __pyx_t_3; - Py_ssize_t __pyx_t_4; - - /* "View.MemoryView":1411 - * size_t itemsize, void *item) nogil: - * cdef Py_ssize_t i - * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<< - * cdef Py_ssize_t extent = shape[0] - * - */ - __pyx_v_stride = (__pyx_v_strides[0]); - - /* "View.MemoryView":1412 - * cdef Py_ssize_t i - * cdef Py_ssize_t stride = strides[0] - * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<< - * - * if ndim == 1: - */ - __pyx_v_extent = (__pyx_v_shape[0]); - - /* "View.MemoryView":1414 - * cdef Py_ssize_t extent = shape[0] - * - * if ndim == 1: # <<<<<<<<<<<<<< - * for i in range(extent): - * memcpy(data, item, itemsize) - */ - __pyx_t_1 = ((__pyx_v_ndim == 1) != 0); - if (__pyx_t_1) { - - /* "View.MemoryView":1415 - * - * if ndim == 1: - * for i in range(extent): # <<<<<<<<<<<<<< - * memcpy(data, item, itemsize) - * data += stride - */ - __pyx_t_2 = __pyx_v_extent; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; - - /* "View.MemoryView":1416 - * if ndim == 1: - * for i in range(extent): - * memcpy(data, item, itemsize) # <<<<<<<<<<<<<< - * data += stride - * else: - */ - (void)(memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize)); - - /* "View.MemoryView":1417 - * for i in range(extent): - * memcpy(data, item, itemsize) - * data += stride # <<<<<<<<<<<<<< - * else: - * for i in range(extent): - */ - __pyx_v_data = (__pyx_v_data + __pyx_v_stride); - } - - /* "View.MemoryView":1414 - * cdef Py_ssize_t extent = shape[0] - * - * if ndim == 1: # <<<<<<<<<<<<<< - * for i in range(extent): - * memcpy(data, item, itemsize) - */ - goto __pyx_L3; - } - - /* "View.MemoryView":1419 - * data += stride - * else: - * for i in range(extent): # <<<<<<<<<<<<<< - * _slice_assign_scalar(data, shape + 1, strides + 1, - * ndim - 1, itemsize, item) - */ - /*else*/ { - __pyx_t_2 = __pyx_v_extent; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_v_i = __pyx_t_4; - - /* "View.MemoryView":1420 - * else: - * for i in range(extent): - * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<< - * ndim - 1, itemsize, item) - * data += stride - */ - __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item); - - /* "View.MemoryView":1422 - * _slice_assign_scalar(data, shape + 1, strides + 1, - * ndim - 1, itemsize, item) - * data += stride # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_data = (__pyx_v_data + __pyx_v_stride); - } - } - __pyx_L3:; - - /* "View.MemoryView":1407 - * - * @cname('__pyx_memoryview__slice_assign_scalar') - * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< - * Py_ssize_t *strides, int ndim, - * size_t itemsize, void *item) nogil: - */ - - /* function exit code */ -} - -/* "(tree fragment)":1 - * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_15View_dot_MemoryView_1__pyx_unpickle_Enum(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_15View_dot_MemoryView_1__pyx_unpickle_Enum = {"__pyx_unpickle_Enum", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_15View_dot_MemoryView_1__pyx_unpickle_Enum, METH_VARARGS|METH_KEYWORDS, 0}; -static PyObject *__pyx_pw_15View_dot_MemoryView_1__pyx_unpickle_Enum(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v___pyx_type = 0; - long __pyx_v___pyx_checksum; - PyObject *__pyx_v___pyx_state = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__pyx_unpickle_Enum (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_type,&__pyx_n_s_pyx_checksum,&__pyx_n_s_pyx_state,0}; - PyObject* values[3] = {0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_type)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_checksum)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_Enum", 1, 3, 3, 1); __PYX_ERR(2, 1, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_state)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_Enum", 1, 3, 3, 2); __PYX_ERR(2, 1, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_unpickle_Enum") < 0)) __PYX_ERR(2, 1, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - } - __pyx_v___pyx_type = values[0]; - __pyx_v___pyx_checksum = __Pyx_PyInt_As_long(values[1]); if (unlikely((__pyx_v___pyx_checksum == (long)-1) && PyErr_Occurred())) __PYX_ERR(2, 1, __pyx_L3_error) - __pyx_v___pyx_state = values[2]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_Enum", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(2, 1, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("View.MemoryView.__pyx_unpickle_Enum", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_15View_dot_MemoryView___pyx_unpickle_Enum(__pyx_self, __pyx_v___pyx_type, __pyx_v___pyx_checksum, __pyx_v___pyx_state); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_15View_dot_MemoryView___pyx_unpickle_Enum(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_v___pyx_PickleError = 0; - PyObject *__pyx_v___pyx_result = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_Enum", 0); - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum != 0xb068931: # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xb068931 = (name))" % __pyx_checksum) - */ - __pyx_t_1 = ((__pyx_v___pyx_checksum != 0xb068931) != 0); - if (__pyx_t_1) { - - /* "(tree fragment)":5 - * cdef object __pyx_result - * if __pyx_checksum != 0xb068931: - * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xb068931 = (name))" % __pyx_checksum) - * __pyx_result = Enum.__new__(__pyx_type) - */ - __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_n_s_PickleError); - __Pyx_GIVEREF(__pyx_n_s_PickleError); - PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); - __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 5, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_t_2); - __pyx_v___pyx_PickleError = __pyx_t_2; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":6 - * if __pyx_checksum != 0xb068931: - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xb068931 = (name))" % __pyx_checksum) # <<<<<<<<<<<<<< - * __pyx_result = Enum.__new__(__pyx_type) - * if __pyx_state is not None: - */ - __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0xb0, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_INCREF(__pyx_v___pyx_PickleError); - __pyx_t_2 = __pyx_v___pyx_PickleError; __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 6, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 6, __pyx_L1_error) - - /* "(tree fragment)":4 - * cdef object __pyx_PickleError - * cdef object __pyx_result - * if __pyx_checksum != 0xb068931: # <<<<<<<<<<<<<< - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xb068931 = (name))" % __pyx_checksum) - */ - } - - /* "(tree fragment)":7 - * from pickle import PickleError as __pyx_PickleError - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xb068931 = (name))" % __pyx_checksum) - * __pyx_result = Enum.__new__(__pyx_type) # <<<<<<<<<<<<<< - * if __pyx_state is not None: - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_MemviewEnum_type), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_v___pyx_result = __pyx_t_3; - __pyx_t_3 = 0; - - /* "(tree fragment)":8 - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xb068931 = (name))" % __pyx_checksum) - * __pyx_result = Enum.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result - */ - __pyx_t_1 = (__pyx_v___pyx_state != Py_None); - __pyx_t_6 = (__pyx_t_1 != 0); - if (__pyx_t_6) { - - /* "(tree fragment)":9 - * __pyx_result = Enum.__new__(__pyx_type) - * if __pyx_state is not None: - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) # <<<<<<<<<<<<<< - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - */ - if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(2, 9, __pyx_L1_error) - __pyx_t_3 = __pyx_unpickle_Enum__set_state(((struct __pyx_MemviewEnum_obj *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":8 - * raise __pyx_PickleError("Incompatible checksums (%s vs 0xb068931 = (name))" % __pyx_checksum) - * __pyx_result = Enum.__new__(__pyx_type) - * if __pyx_state is not None: # <<<<<<<<<<<<<< - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result - */ - } - - /* "(tree fragment)":10 - * if __pyx_state is not None: - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result # <<<<<<<<<<<<<< - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0] - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v___pyx_result); - __pyx_r = __pyx_v___pyx_result; - goto __pyx_L0; - - /* "(tree fragment)":1 - * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("View.MemoryView.__pyx_unpickle_Enum", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v___pyx_PickleError); - __Pyx_XDECREF(__pyx_v___pyx_result); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":11 - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): - */ - -static PyObject *__pyx_unpickle_Enum__set_state(struct __pyx_MemviewEnum_obj *__pyx_v___pyx_result, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - Py_ssize_t __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_unpickle_Enum__set_state", 0); - - /* "(tree fragment)":12 - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0] # <<<<<<<<<<<<<< - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[1]) - */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(2, 12, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 12, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_v___pyx_result->name); - __Pyx_DECREF(__pyx_v___pyx_result->name); - __pyx_v___pyx_result->name = __pyx_t_1; - __pyx_t_1 = 0; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[1]) - */ - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(2, 13, __pyx_L1_error) - } - __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(2, 13, __pyx_L1_error) - __pyx_t_4 = ((__pyx_t_3 > 1) != 0); - if (__pyx_t_4) { - } else { - __pyx_t_2 = __pyx_t_4; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 13, __pyx_L1_error) - __pyx_t_5 = (__pyx_t_4 != 0); - __pyx_t_2 = __pyx_t_5; - __pyx_L4_bool_binop_done:; - if (__pyx_t_2) { - - /* "(tree fragment)":14 - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): - * __pyx_result.__dict__.update(__pyx_state[1]) # <<<<<<<<<<<<<< - */ - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(__pyx_v___pyx_state == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(2, 14, __pyx_L1_error) - } - __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_8 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_8)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_8); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - } - } - __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 14, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "(tree fragment)":13 - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< - * __pyx_result.__dict__.update(__pyx_state[1]) - */ - } - - /* "(tree fragment)":11 - * __pyx_unpickle_Enum__set_state( __pyx_result, __pyx_state) - * return __pyx_result - * cdef __pyx_unpickle_Enum__set_state(Enum __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< - * __pyx_result.name = __pyx_state[0] - * if len(__pyx_state) > 1 and hasattr(__pyx_result, '__dict__'): - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("View.MemoryView.__pyx_unpickle_Enum__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "BufferFormatFromTypeInfo":1463 - * - * @cname('__pyx_format_from_typeinfo') - * cdef bytes format_from_typeinfo(__Pyx_TypeInfo *type): # <<<<<<<<<<<<<< - * cdef __Pyx_StructField *field - * cdef __pyx_typeinfo_string fmt - */ - -static PyObject *__pyx_format_from_typeinfo(__Pyx_TypeInfo *__pyx_v_type) { - __Pyx_StructField *__pyx_v_field; - struct __pyx_typeinfo_string __pyx_v_fmt; - PyObject *__pyx_v_part = 0; - PyObject *__pyx_v_result = 0; - PyObject *__pyx_v_alignment = NULL; - PyObject *__pyx_v_parts = NULL; - PyObject *__pyx_v_extents = NULL; - int __pyx_v_i; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - __Pyx_StructField *__pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - int __pyx_t_7; - int __pyx_t_8; - int __pyx_t_9; - int __pyx_t_10; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("format_from_typeinfo", 0); - - /* "BufferFormatFromTypeInfo":1468 - * cdef bytes part, result - * - * if type.typegroup == 'S': # <<<<<<<<<<<<<< - * assert type.fields != NULL and type.fields.type != NULL - * - */ - __pyx_t_1 = ((__pyx_v_type->typegroup == 'S') != 0); - if (__pyx_t_1) { - - /* "BufferFormatFromTypeInfo":1469 - * - * if type.typegroup == 'S': - * assert type.fields != NULL and type.fields.type != NULL # <<<<<<<<<<<<<< - * - * if type.flags & __PYX_BUF_FLAGS_PACKED_STRUCT: - */ - #ifndef CYTHON_WITHOUT_ASSERTIONS - if (unlikely(!Py_OptimizeFlag)) { - __pyx_t_2 = ((__pyx_v_type->fields != NULL) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_2 = ((__pyx_v_type->fields->type != NULL) != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L4_bool_binop_done:; - if (unlikely(!__pyx_t_1)) { - PyErr_SetNone(PyExc_AssertionError); - __PYX_ERR(2, 1469, __pyx_L1_error) - } - } - #endif - - /* "BufferFormatFromTypeInfo":1471 - * assert type.fields != NULL and type.fields.type != NULL - * - * if type.flags & __PYX_BUF_FLAGS_PACKED_STRUCT: # <<<<<<<<<<<<<< - * alignment = b'^' - * else: - */ - __pyx_t_1 = ((__pyx_v_type->flags & __PYX_BUF_FLAGS_PACKED_STRUCT) != 0); - if (__pyx_t_1) { - - /* "BufferFormatFromTypeInfo":1472 - * - * if type.flags & __PYX_BUF_FLAGS_PACKED_STRUCT: - * alignment = b'^' # <<<<<<<<<<<<<< - * else: - * alignment = b'' - */ - __Pyx_INCREF(__pyx_kp_b__26); - __pyx_v_alignment = __pyx_kp_b__26; - - /* "BufferFormatFromTypeInfo":1471 - * assert type.fields != NULL and type.fields.type != NULL - * - * if type.flags & __PYX_BUF_FLAGS_PACKED_STRUCT: # <<<<<<<<<<<<<< - * alignment = b'^' - * else: - */ - goto __pyx_L6; - } - - /* "BufferFormatFromTypeInfo":1474 - * alignment = b'^' - * else: - * alignment = b'' # <<<<<<<<<<<<<< - * - * parts = [b"T{"] - */ - /*else*/ { - __Pyx_INCREF(__pyx_kp_b__27); - __pyx_v_alignment = __pyx_kp_b__27; - } - __pyx_L6:; - - /* "BufferFormatFromTypeInfo":1476 - * alignment = b'' - * - * parts = [b"T{"] # <<<<<<<<<<<<<< - * field = type.fields - * - */ - __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1476, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_kp_b_T); - __Pyx_GIVEREF(__pyx_kp_b_T); - PyList_SET_ITEM(__pyx_t_3, 0, __pyx_kp_b_T); - __pyx_v_parts = ((PyObject*)__pyx_t_3); - __pyx_t_3 = 0; - - /* "BufferFormatFromTypeInfo":1477 - * - * parts = [b"T{"] - * field = type.fields # <<<<<<<<<<<<<< - * - * while field.type: - */ - __pyx_t_4 = __pyx_v_type->fields; - __pyx_v_field = __pyx_t_4; - - /* "BufferFormatFromTypeInfo":1479 - * field = type.fields - * - * while field.type: # <<<<<<<<<<<<<< - * part = format_from_typeinfo(field.type) - * parts.append(part + b':' + field.name + b':') - */ - while (1) { - __pyx_t_1 = (__pyx_v_field->type != 0); - if (!__pyx_t_1) break; - - /* "BufferFormatFromTypeInfo":1480 - * - * while field.type: - * part = format_from_typeinfo(field.type) # <<<<<<<<<<<<<< - * parts.append(part + b':' + field.name + b':') - * field += 1 - */ - __pyx_t_3 = __pyx_format_from_typeinfo(__pyx_v_field->type); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1480, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_XDECREF_SET(__pyx_v_part, ((PyObject*)__pyx_t_3)); - __pyx_t_3 = 0; - - /* "BufferFormatFromTypeInfo":1481 - * while field.type: - * part = format_from_typeinfo(field.type) - * parts.append(part + b':' + field.name + b':') # <<<<<<<<<<<<<< - * field += 1 - * - */ - __pyx_t_3 = PyNumber_Add(__pyx_v_part, __pyx_kp_b__28); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1481, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_field->name); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 1481, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = PyNumber_Add(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 1481, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = PyNumber_Add(__pyx_t_6, __pyx_kp_b__28); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 1481, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_7 = __Pyx_PyList_Append(__pyx_v_parts, __pyx_t_5); if (unlikely(__pyx_t_7 == ((int)-1))) __PYX_ERR(2, 1481, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "BufferFormatFromTypeInfo":1482 - * part = format_from_typeinfo(field.type) - * parts.append(part + b':' + field.name + b':') - * field += 1 # <<<<<<<<<<<<<< - * - * result = alignment.join(parts) + b'}' - */ - __pyx_v_field = (__pyx_v_field + 1); - } - - /* "BufferFormatFromTypeInfo":1484 - * field += 1 - * - * result = alignment.join(parts) + b'}' # <<<<<<<<<<<<<< - * else: - * fmt = __Pyx_TypeInfoToFormat(type) - */ - __pyx_t_5 = __Pyx_PyBytes_Join(__pyx_v_alignment, __pyx_v_parts); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 1484, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_kp_b__29); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 1484, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (!(likely(PyBytes_CheckExact(__pyx_t_6))||((__pyx_t_6) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_6)->tp_name), 0))) __PYX_ERR(2, 1484, __pyx_L1_error) - __pyx_v_result = ((PyObject*)__pyx_t_6); - __pyx_t_6 = 0; - - /* "BufferFormatFromTypeInfo":1468 - * cdef bytes part, result - * - * if type.typegroup == 'S': # <<<<<<<<<<<<<< - * assert type.fields != NULL and type.fields.type != NULL - * - */ - goto __pyx_L3; - } - - /* "BufferFormatFromTypeInfo":1486 - * result = alignment.join(parts) + b'}' - * else: - * fmt = __Pyx_TypeInfoToFormat(type) # <<<<<<<<<<<<<< - * if type.arraysize[0]: - * extents = [unicode(type.arraysize[i]) for i in range(type.ndim)] - */ - /*else*/ { - __pyx_v_fmt = __Pyx_TypeInfoToFormat(__pyx_v_type); - - /* "BufferFormatFromTypeInfo":1487 - * else: - * fmt = __Pyx_TypeInfoToFormat(type) - * if type.arraysize[0]: # <<<<<<<<<<<<<< - * extents = [unicode(type.arraysize[i]) for i in range(type.ndim)] - * result = (u"(%s)" % u','.join(extents)).encode('ascii') + fmt.string - */ - __pyx_t_1 = ((__pyx_v_type->arraysize[0]) != 0); - if (__pyx_t_1) { - - /* "BufferFormatFromTypeInfo":1488 - * fmt = __Pyx_TypeInfoToFormat(type) - * if type.arraysize[0]: - * extents = [unicode(type.arraysize[i]) for i in range(type.ndim)] # <<<<<<<<<<<<<< - * result = (u"(%s)" % u','.join(extents)).encode('ascii') + fmt.string - * else: - */ - __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 1488, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_8 = __pyx_v_type->ndim; - __pyx_t_9 = __pyx_t_8; - for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) { - __pyx_v_i = __pyx_t_10; - __pyx_t_5 = __Pyx_PyInt_FromSize_t((__pyx_v_type->arraysize[__pyx_v_i])); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 1488, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_3 = __Pyx_PyObject_Unicode(__pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1488, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(__Pyx_ListComp_Append(__pyx_t_6, (PyObject*)__pyx_t_3))) __PYX_ERR(2, 1488, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - __pyx_v_extents = ((PyObject*)__pyx_t_6); - __pyx_t_6 = 0; - - /* "BufferFormatFromTypeInfo":1489 - * if type.arraysize[0]: - * extents = [unicode(type.arraysize[i]) for i in range(type.ndim)] - * result = (u"(%s)" % u','.join(extents)).encode('ascii') + fmt.string # <<<<<<<<<<<<<< - * else: - * result = fmt.string - */ - __pyx_t_6 = PyUnicode_Join(__pyx_kp_u__30, __pyx_v_extents); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 1489, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_s, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1489, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_6 = PyUnicode_AsASCIIString(((PyObject*)__pyx_t_3)); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 1489, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_FromString(__pyx_v_fmt.string); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1489, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyNumber_Add(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 1489, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (!(likely(PyBytes_CheckExact(__pyx_t_5))||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_5)->tp_name), 0))) __PYX_ERR(2, 1489, __pyx_L1_error) - __pyx_v_result = ((PyObject*)__pyx_t_5); - __pyx_t_5 = 0; - - /* "BufferFormatFromTypeInfo":1487 - * else: - * fmt = __Pyx_TypeInfoToFormat(type) - * if type.arraysize[0]: # <<<<<<<<<<<<<< - * extents = [unicode(type.arraysize[i]) for i in range(type.ndim)] - * result = (u"(%s)" % u','.join(extents)).encode('ascii') + fmt.string - */ - goto __pyx_L9; - } - - /* "BufferFormatFromTypeInfo":1491 - * result = (u"(%s)" % u','.join(extents)).encode('ascii') + fmt.string - * else: - * result = fmt.string # <<<<<<<<<<<<<< - * - * return result - */ - /*else*/ { - __pyx_t_5 = __Pyx_PyObject_FromString(__pyx_v_fmt.string); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 1491, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_v_result = ((PyObject*)__pyx_t_5); - __pyx_t_5 = 0; - } - __pyx_L9:; - } - __pyx_L3:; - - /* "BufferFormatFromTypeInfo":1493 - * result = fmt.string - * - * return result # <<<<<<<<<<<<<< - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_result); - __pyx_r = __pyx_v_result; - goto __pyx_L0; - - /* "BufferFormatFromTypeInfo":1463 - * - * @cname('__pyx_format_from_typeinfo') - * cdef bytes format_from_typeinfo(__Pyx_TypeInfo *type): # <<<<<<<<<<<<<< - * cdef __Pyx_StructField *field - * cdef __pyx_typeinfo_string fmt - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("BufferFormatFromTypeInfo.format_from_typeinfo", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_part); - __Pyx_XDECREF(__pyx_v_result); - __Pyx_XDECREF(__pyx_v_alignment); - __Pyx_XDECREF(__pyx_v_parts); - __Pyx_XDECREF(__pyx_v_extents); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} -static struct __pyx_vtabstruct_array __pyx_vtable_array; - -static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_array_obj *p; - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - p = ((struct __pyx_array_obj *)o); - p->__pyx_vtab = __pyx_vtabptr_array; - p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None); - p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None); - if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) goto bad; - return o; - bad: - Py_DECREF(o); o = 0; - return NULL; -} - -static void __pyx_tp_dealloc_array(PyObject *o) { - struct __pyx_array_obj *p = (struct __pyx_array_obj *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_array___dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); - } - Py_CLEAR(p->mode); - Py_CLEAR(p->_format); - (*Py_TYPE(o)->tp_free)(o); -} -static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) { - PyObject *r; - PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; - r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); - Py_DECREF(x); - return r; -} - -static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) { - if (v) { - return __pyx_array___setitem__(o, i, v); - } - else { - PyErr_Format(PyExc_NotImplementedError, - "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name); - return -1; - } -} - -static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) { - PyObject *v = __Pyx_PyObject_GenericGetAttr(o, n); - if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - v = __pyx_array___getattr__(o, n); - } - return v; -} - -static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(o); -} - -static PyMethodDef __pyx_methods_array[] = { - {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0}, - {"__reduce_cython__", (PyCFunction)__pyx_pw___pyx_array_1__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw___pyx_array_3__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets_array[] = { - {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, (char *)0, 0}, - {0, 0, 0, 0, 0} -}; - -static PySequenceMethods __pyx_tp_as_sequence_array = { - __pyx_array___len__, /*sq_length*/ - 0, /*sq_concat*/ - 0, /*sq_repeat*/ - __pyx_sq_item_array, /*sq_item*/ - 0, /*sq_slice*/ - 0, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - 0, /*sq_contains*/ - 0, /*sq_inplace_concat*/ - 0, /*sq_inplace_repeat*/ -}; - -static PyMappingMethods __pyx_tp_as_mapping_array = { - __pyx_array___len__, /*mp_length*/ - __pyx_array___getitem__, /*mp_subscript*/ - __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/ -}; - -static PyBufferProcs __pyx_tp_as_buffer_array = { - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getreadbuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getwritebuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getsegcount*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getcharbuffer*/ - #endif - __pyx_array_getbuffer, /*bf_getbuffer*/ - 0, /*bf_releasebuffer*/ -}; - -static PyTypeObject __pyx_type___pyx_array = { - PyVarObject_HEAD_INIT(0, 0) - "easyCore.Utils.coord_cython.array", /*tp_name*/ - sizeof(struct __pyx_array_obj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_array, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - &__pyx_tp_as_sequence_array, /*tp_as_sequence*/ - &__pyx_tp_as_mapping_array, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - __pyx_tp_getattro_array, /*tp_getattro*/ - 0, /*tp_setattro*/ - &__pyx_tp_as_buffer_array, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_array, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_array, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_array, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; - -static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { - struct __pyx_MemviewEnum_obj *p; - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - p = ((struct __pyx_MemviewEnum_obj *)o); - p->name = Py_None; Py_INCREF(Py_None); - return o; -} - -static void __pyx_tp_dealloc_Enum(PyObject *o) { - struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - Py_CLEAR(p->name); - (*Py_TYPE(o)->tp_free)(o); -} - -static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; - if (p->name) { - e = (*v)(p->name, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_Enum(PyObject *o) { - PyObject* tmp; - struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; - tmp = ((PyObject*)p->name); - p->name = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - return 0; -} - -static PyMethodDef __pyx_methods_Enum[] = { - {"__reduce_cython__", (PyCFunction)__pyx_pw___pyx_MemviewEnum_1__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw___pyx_MemviewEnum_3__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static PyTypeObject __pyx_type___pyx_MemviewEnum = { - PyVarObject_HEAD_INIT(0, 0) - "easyCore.Utils.coord_cython.Enum", /*tp_name*/ - sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_Enum, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - __pyx_MemviewEnum___repr__, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_Enum, /*tp_traverse*/ - __pyx_tp_clear_Enum, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_Enum, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - __pyx_MemviewEnum___init__, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_Enum, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; -static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview; - -static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_memoryview_obj *p; - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - p = ((struct __pyx_memoryview_obj *)o); - p->__pyx_vtab = __pyx_vtabptr_memoryview; - p->obj = Py_None; Py_INCREF(Py_None); - p->_size = Py_None; Py_INCREF(Py_None); - p->_array_interface = Py_None; Py_INCREF(Py_None); - p->view.obj = NULL; - if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) goto bad; - return o; - bad: - Py_DECREF(o); o = 0; - return NULL; -} - -static void __pyx_tp_dealloc_memoryview(PyObject *o) { - struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_memoryview___dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); - } - Py_CLEAR(p->obj); - Py_CLEAR(p->_size); - Py_CLEAR(p->_array_interface); - (*Py_TYPE(o)->tp_free)(o); -} - -static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; - if (p->obj) { - e = (*v)(p->obj, a); if (e) return e; - } - if (p->_size) { - e = (*v)(p->_size, a); if (e) return e; - } - if (p->_array_interface) { - e = (*v)(p->_array_interface, a); if (e) return e; - } - if (p->view.obj) { - e = (*v)(p->view.obj, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_memoryview(PyObject *o) { - PyObject* tmp; - struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; - tmp = ((PyObject*)p->obj); - p->obj = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_size); - p->_size = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - tmp = ((PyObject*)p->_array_interface); - p->_array_interface = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - Py_CLEAR(p->view.obj); - return 0; -} -static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) { - PyObject *r; - PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; - r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); - Py_DECREF(x); - return r; -} - -static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) { - if (v) { - return __pyx_memoryview___setitem__(o, i, v); - } - else { - PyErr_Format(PyExc_NotImplementedError, - "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name); - return -1; - } -} - -static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(o); -} - -static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(o); -} - -static PyMethodDef __pyx_methods_memoryview[] = { - {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0}, - {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0}, - {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0}, - {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0}, - {"__reduce_cython__", (PyCFunction)__pyx_pw___pyx_memoryview_1__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw___pyx_memoryview_3__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets_memoryview[] = { - {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, (char *)0, 0}, - {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, (char *)0, 0}, - {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, (char *)0, 0}, - {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, (char *)0, 0}, - {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, (char *)0, 0}, - {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, (char *)0, 0}, - {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, (char *)0, 0}, - {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, (char *)0, 0}, - {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, (char *)0, 0}, - {0, 0, 0, 0, 0} -}; - -static PySequenceMethods __pyx_tp_as_sequence_memoryview = { - __pyx_memoryview___len__, /*sq_length*/ - 0, /*sq_concat*/ - 0, /*sq_repeat*/ - __pyx_sq_item_memoryview, /*sq_item*/ - 0, /*sq_slice*/ - 0, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - 0, /*sq_contains*/ - 0, /*sq_inplace_concat*/ - 0, /*sq_inplace_repeat*/ -}; - -static PyMappingMethods __pyx_tp_as_mapping_memoryview = { - __pyx_memoryview___len__, /*mp_length*/ - __pyx_memoryview___getitem__, /*mp_subscript*/ - __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/ -}; - -static PyBufferProcs __pyx_tp_as_buffer_memoryview = { - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getreadbuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getwritebuffer*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getsegcount*/ - #endif - #if PY_MAJOR_VERSION < 3 - 0, /*bf_getcharbuffer*/ - #endif - __pyx_memoryview_getbuffer, /*bf_getbuffer*/ - 0, /*bf_releasebuffer*/ -}; - -static PyTypeObject __pyx_type___pyx_memoryview = { - PyVarObject_HEAD_INIT(0, 0) - "easyCore.Utils.coord_cython.memoryview", /*tp_name*/ - sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_memoryview, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - __pyx_memoryview___repr__, /*tp_repr*/ - 0, /*tp_as_number*/ - &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/ - &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - __pyx_memoryview___str__, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - __pyx_tp_traverse_memoryview, /*tp_traverse*/ - __pyx_tp_clear_memoryview, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_memoryview, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_memoryview, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_memoryview, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; -static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice; - -static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_memoryviewslice_obj *p; - PyObject *o = __pyx_tp_new_memoryview(t, a, k); - if (unlikely(!o)) return 0; - p = ((struct __pyx_memoryviewslice_obj *)o); - p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice; - p->from_object = Py_None; Py_INCREF(Py_None); - p->from_slice.memview = NULL; - return o; -} - -static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) { - struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_memoryviewslice___dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); - } - Py_CLEAR(p->from_object); - PyObject_GC_Track(o); - __pyx_tp_dealloc_memoryview(o); -} - -static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; - e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e; - if (p->from_object) { - e = (*v)(p->from_object, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear__memoryviewslice(PyObject *o) { - PyObject* tmp; - struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; - __pyx_tp_clear_memoryview(o); - tmp = ((PyObject*)p->from_object); - p->from_object = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - __PYX_XDEC_MEMVIEW(&p->from_slice, 1); - return 0; -} - -static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_15View_dot_MemoryView_16_memoryviewslice_4base_1__get__(o); -} - -static PyMethodDef __pyx_methods__memoryviewslice[] = { - {"__reduce_cython__", (PyCFunction)__pyx_pw___pyx_memoryviewslice_1__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw___pyx_memoryviewslice_3__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = { - {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, (char *)0, 0}, - {0, 0, 0, 0, 0} -}; - -static PyTypeObject __pyx_type___pyx_memoryviewslice = { - PyVarObject_HEAD_INIT(0, 0) - "easyCore.Utils.coord_cython._memoryviewslice", /*tp_name*/ - sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - #if CYTHON_COMPILING_IN_PYPY - __pyx_memoryview___repr__, /*tp_repr*/ - #else - 0, /*tp_repr*/ - #endif - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - #if CYTHON_COMPILING_IN_PYPY - __pyx_memoryview___str__, /*tp_str*/ - #else - 0, /*tp_str*/ - #endif - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - "Internal class for passing memoryview slices to Python", /*tp_doc*/ - __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/ - __pyx_tp_clear__memoryviewslice, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods__memoryviewslice, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets__memoryviewslice, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new__memoryviewslice, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif -}; - -static PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; - -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec_coord_cython(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec_coord_cython}, - {0, NULL} -}; -#endif - -static struct PyModuleDef __pyx_moduledef = { - PyModuleDef_HEAD_INIT, - "coord_cython", - __pyx_k_Utilities_for_manipulating_coor, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #else - -1, /* m_size */ - #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ - #else - NULL, /* m_reload */ - #endif - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; -#endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif - -static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_kp_s_1_0, __pyx_k_1_0, sizeof(__pyx_k_1_0), 0, 0, 1, 0}, - {&__pyx_n_s_ASCII, __pyx_k_ASCII, sizeof(__pyx_k_ASCII), 0, 0, 1, 1}, - {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0}, - {&__pyx_n_s_C, __pyx_k_C, sizeof(__pyx_k_C), 0, 0, 1, 1}, - {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0}, - {&__pyx_kp_s_Cannot_assign_to_read_only_memor, __pyx_k_Cannot_assign_to_read_only_memor, sizeof(__pyx_k_Cannot_assign_to_read_only_memor), 0, 0, 1, 0}, - {&__pyx_kp_s_Cannot_create_writable_memory_vi, __pyx_k_Cannot_create_writable_memory_vi, sizeof(__pyx_k_Cannot_create_writable_memory_vi), 0, 0, 1, 0}, - {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0}, - {&__pyx_kp_s_Copyright_2011_The_Materials_Pro, __pyx_k_Copyright_2011_The_Materials_Pro, sizeof(__pyx_k_Copyright_2011_The_Materials_Pro), 0, 0, 1, 0}, - {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1}, - {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0}, - {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0}, - {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0}, - {&__pyx_n_s_I, __pyx_k_I, sizeof(__pyx_k_I), 0, 0, 1, 1}, - {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, - {&__pyx_kp_s_Incompatible_checksums_s_vs_0xb0, __pyx_k_Incompatible_checksums_s_vs_0xb0, sizeof(__pyx_k_Incompatible_checksums_s_vs_0xb0), 0, 0, 1, 0}, - {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1}, - {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0}, - {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0}, - {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0}, - {&__pyx_n_s_J, __pyx_k_J, sizeof(__pyx_k_J), 0, 0, 1, 1}, - {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1}, - {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0}, - {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0}, - {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0}, - {&__pyx_kp_s_Nov_27_2011, __pyx_k_Nov_27_2011, sizeof(__pyx_k_Nov_27_2011), 0, 0, 1, 0}, - {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1}, - {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0}, - {&__pyx_n_s_PickleError, __pyx_k_PickleError, sizeof(__pyx_k_PickleError), 0, 0, 1, 1}, - {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, - {&__pyx_kp_s_Something_wrong_with_the_inputs, __pyx_k_Something_wrong_with_the_inputs, sizeof(__pyx_k_Something_wrong_with_the_inputs), 0, 0, 1, 0}, - {&__pyx_kp_b_T, __pyx_k_T, sizeof(__pyx_k_T), 0, 0, 0, 0}, - {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, - {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0}, - {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, - {&__pyx_n_s_View_MemoryView, __pyx_k_View_MemoryView, sizeof(__pyx_k_View_MemoryView), 0, 0, 1, 1}, - {&__pyx_kp_s_Will_Richards, __pyx_k_Will_Richards, sizeof(__pyx_k_Will_Richards), 0, 0, 1, 0}, - {&__pyx_kp_b__26, __pyx_k__26, sizeof(__pyx_k__26), 0, 0, 0, 0}, - {&__pyx_kp_b__27, __pyx_k__27, sizeof(__pyx_k__27), 0, 0, 0, 0}, - {&__pyx_kp_b__28, __pyx_k__28, sizeof(__pyx_k__28), 0, 0, 0, 0}, - {&__pyx_kp_b__29, __pyx_k__29, sizeof(__pyx_k__29), 0, 0, 0, 0}, - {&__pyx_kp_u__30, __pyx_k__30, sizeof(__pyx_k__30), 0, 1, 0, 0}, - {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1}, - {&__pyx_n_s_arange, __pyx_k_arange, sizeof(__pyx_k_arange), 0, 0, 1, 1}, - {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1}, - {&__pyx_n_s_atleast_2d, __pyx_k_atleast_2d, sizeof(__pyx_k_atleast_2d), 0, 0, 1, 1}, - {&__pyx_n_s_atol, __pyx_k_atol, sizeof(__pyx_k_atol), 0, 0, 1, 1}, - {&__pyx_n_s_author, __pyx_k_author, sizeof(__pyx_k_author), 0, 0, 1, 1}, - {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1}, - {&__pyx_n_s_best, __pyx_k_best, sizeof(__pyx_k_best), 0, 0, 1, 1}, - {&__pyx_n_s_bestK, __pyx_k_bestK, sizeof(__pyx_k_bestK), 0, 0, 1, 1}, - {&__pyx_n_s_bestk, __pyx_k_bestk, sizeof(__pyx_k_bestk), 0, 0, 1, 1}, - {&__pyx_n_s_brange, __pyx_k_brange, sizeof(__pyx_k_brange), 0, 0, 1, 1}, - {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1}, - {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1}, - {&__pyx_n_s_c_inds, __pyx_k_c_inds, sizeof(__pyx_k_c_inds), 0, 0, 1, 1}, - {&__pyx_n_s_cart_f1, __pyx_k_cart_f1, sizeof(__pyx_k_cart_f1), 0, 0, 1, 1}, - {&__pyx_n_s_cart_f2, __pyx_k_cart_f2, sizeof(__pyx_k_cart_f2), 0, 0, 1, 1}, - {&__pyx_n_s_cart_im, __pyx_k_cart_im, sizeof(__pyx_k_cart_im), 0, 0, 1, 1}, - {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0}, - {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0}, - {&__pyx_n_s_coord_list_mapping_pbc, __pyx_k_coord_list_mapping_pbc, sizeof(__pyx_k_coord_list_mapping_pbc), 0, 0, 1, 1}, - {&__pyx_n_s_copy, __pyx_k_copy, sizeof(__pyx_k_copy), 0, 0, 1, 1}, - {&__pyx_n_s_copyright, __pyx_k_copyright, sizeof(__pyx_k_copyright), 0, 0, 1, 1}, - {&__pyx_n_s_crange, __pyx_k_crange, sizeof(__pyx_k_crange), 0, 0, 1, 1}, - {&__pyx_n_s_d, __pyx_k_d, sizeof(__pyx_k_d), 0, 0, 1, 1}, - {&__pyx_n_s_d2, __pyx_k_d2, sizeof(__pyx_k_d2), 0, 0, 1, 1}, - {&__pyx_n_s_da, __pyx_k_da, sizeof(__pyx_k_da), 0, 0, 1, 1}, - {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1}, - {&__pyx_n_s_db, __pyx_k_db, sizeof(__pyx_k_db), 0, 0, 1, 1}, - {&__pyx_n_s_dc, __pyx_k_dc, sizeof(__pyx_k_dc), 0, 0, 1, 1}, - {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1}, - {&__pyx_n_s_ds, __pyx_k_ds, sizeof(__pyx_k_ds), 0, 0, 1, 1}, - {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1}, - {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1}, - {&__pyx_n_s_easyCore_Utils_coord_cython, __pyx_k_easyCore_Utils_coord_cython, sizeof(__pyx_k_easyCore_Utils_coord_cython), 0, 0, 1, 1}, - {&__pyx_kp_s_easyCore_Utils_coord_cython_pyx, __pyx_k_easyCore_Utils_coord_cython_pyx, sizeof(__pyx_k_easyCore_Utils_coord_cython_pyx), 0, 0, 1, 0}, - {&__pyx_n_s_email, __pyx_k_email, sizeof(__pyx_k_email), 0, 0, 1, 1}, - {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1}, - {&__pyx_n_s_encode, __pyx_k_encode, sizeof(__pyx_k_encode), 0, 0, 1, 1}, - {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1}, - {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1}, - {&__pyx_n_s_fc1, __pyx_k_fc1, sizeof(__pyx_k_fc1), 0, 0, 1, 1}, - {&__pyx_n_s_fc2, __pyx_k_fc2, sizeof(__pyx_k_fc2), 0, 0, 1, 1}, - {&__pyx_n_s_fcoords1, __pyx_k_fcoords1, sizeof(__pyx_k_fcoords1), 0, 0, 1, 1}, - {&__pyx_n_s_fcoords2, __pyx_k_fcoords2, sizeof(__pyx_k_fcoords2), 0, 0, 1, 1}, - {&__pyx_n_s_fdist, __pyx_k_fdist, sizeof(__pyx_k_fdist), 0, 0, 1, 1}, - {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1}, - {&__pyx_n_s_float, __pyx_k_float, sizeof(__pyx_k_float), 0, 0, 1, 1}, - {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, - {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1}, - {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1}, - {&__pyx_n_s_ftol, __pyx_k_ftol, sizeof(__pyx_k_ftol), 0, 0, 1, 1}, - {&__pyx_n_s_get_lll_frac_coords, __pyx_k_get_lll_frac_coords, sizeof(__pyx_k_get_lll_frac_coords), 0, 0, 1, 1}, - {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, - {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0}, - {&__pyx_n_s_has_ftol, __pyx_k_has_ftol, sizeof(__pyx_k_has_ftol), 0, 0, 1, 1}, - {&__pyx_n_s_has_mask, __pyx_k_has_mask, sizeof(__pyx_k_has_mask), 0, 0, 1, 1}, - {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, - {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1}, - {&__pyx_n_s_images, __pyx_k_images, sizeof(__pyx_k_images), 0, 0, 1, 1}, - {&__pyx_n_s_images_t, __pyx_k_images_t, sizeof(__pyx_k_images_t), 0, 0, 1, 1}, - {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, - {&__pyx_n_s_inc_d, __pyx_k_inc_d, sizeof(__pyx_k_inc_d), 0, 0, 1, 1}, - {&__pyx_n_s_inds, __pyx_k_inds, sizeof(__pyx_k_inds), 0, 0, 1, 1}, - {&__pyx_n_s_int, __pyx_k_int, sizeof(__pyx_k_int), 0, 0, 1, 1}, - {&__pyx_n_s_int_2, __pyx_k_int_2, sizeof(__pyx_k_int_2), 0, 0, 1, 1}, - {&__pyx_n_s_is_coord_subset_pbc, __pyx_k_is_coord_subset_pbc, sizeof(__pyx_k_is_coord_subset_pbc), 0, 0, 1, 1}, - {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1}, - {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0}, - {&__pyx_n_s_j, __pyx_k_j, sizeof(__pyx_k_j), 0, 0, 1, 1}, - {&__pyx_n_s_join, __pyx_k_join, sizeof(__pyx_k_join), 0, 0, 1, 1}, - {&__pyx_n_s_k, __pyx_k_k, sizeof(__pyx_k_k), 0, 0, 1, 1}, - {&__pyx_n_s_l, __pyx_k_l, sizeof(__pyx_k_l), 0, 0, 1, 1}, - {&__pyx_n_s_lat, __pyx_k_lat, sizeof(__pyx_k_lat), 0, 0, 1, 1}, - {&__pyx_n_s_lattice, __pyx_k_lattice, sizeof(__pyx_k_lattice), 0, 0, 1, 1}, - {&__pyx_n_s_lll_frac_tol, __pyx_k_lll_frac_tol, sizeof(__pyx_k_lll_frac_tol), 0, 0, 1, 1}, - {&__pyx_n_s_lll_matrix, __pyx_k_lll_matrix, sizeof(__pyx_k_lll_matrix), 0, 0, 1, 1}, - {&__pyx_n_s_m, __pyx_k_m, sizeof(__pyx_k_m), 0, 0, 1, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_maintainer, __pyx_k_maintainer, sizeof(__pyx_k_maintainer), 0, 0, 1, 1}, - {&__pyx_n_s_mask, __pyx_k_mask, sizeof(__pyx_k_mask), 0, 0, 1, 1}, - {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1}, - {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1}, - {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, - {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1}, - {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1}, - {&__pyx_n_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 1}, - {&__pyx_kp_s_no_default___reduce___due_to_non, __pyx_k_no_default___reduce___due_to_non, sizeof(__pyx_k_no_default___reduce___due_to_non), 0, 0, 1, 0}, - {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, - {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, - {&__pyx_kp_s_numpy_core_multiarray_failed_to, __pyx_k_numpy_core_multiarray_failed_to, sizeof(__pyx_k_numpy_core_multiarray_failed_to), 0, 0, 1, 0}, - {&__pyx_kp_s_numpy_core_umath_failed_to_impor, __pyx_k_numpy_core_umath_failed_to_impor, sizeof(__pyx_k_numpy_core_umath_failed_to_impor), 0, 0, 1, 0}, - {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1}, - {&__pyx_n_s_ok, __pyx_k_ok, sizeof(__pyx_k_ok), 0, 0, 1, 1}, - {&__pyx_n_s_ok_inner, __pyx_k_ok_inner, sizeof(__pyx_k_ok_inner), 0, 0, 1, 1}, - {&__pyx_n_s_ok_outer, __pyx_k_ok_outer, sizeof(__pyx_k_ok_outer), 0, 0, 1, 1}, - {&__pyx_n_s_order, __pyx_k_order, sizeof(__pyx_k_order), 0, 0, 1, 1}, - {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1}, - {&__pyx_n_s_pbc_shortest_vectors, __pyx_k_pbc_shortest_vectors, sizeof(__pyx_k_pbc_shortest_vectors), 0, 0, 1, 1}, - {&__pyx_n_s_pickle, __pyx_k_pickle, sizeof(__pyx_k_pickle), 0, 0, 1, 1}, - {&__pyx_n_s_pre_im, __pyx_k_pre_im, sizeof(__pyx_k_pre_im), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_PickleError, __pyx_k_pyx_PickleError, sizeof(__pyx_k_pyx_PickleError), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_checksum, __pyx_k_pyx_checksum, sizeof(__pyx_k_pyx_checksum), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_result, __pyx_k_pyx_result, sizeof(__pyx_k_pyx_result), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_type, __pyx_k_pyx_type, sizeof(__pyx_k_pyx_type), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_unpickle_Enum, __pyx_k_pyx_unpickle_Enum, sizeof(__pyx_k_pyx_unpickle_Enum), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, - {&__pyx_n_s_r, __pyx_k_r, sizeof(__pyx_k_r), 0, 0, 1, 1}, - {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, - {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, - {&__pyx_n_s_reshape, __pyx_k_reshape, sizeof(__pyx_k_reshape), 0, 0, 1, 1}, - {&__pyx_n_s_return_d2, __pyx_k_return_d2, sizeof(__pyx_k_return_d2), 0, 0, 1, 1}, - {&__pyx_kp_u_s, __pyx_k_s, sizeof(__pyx_k_s), 0, 1, 0, 0}, - {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, - {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, - {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1}, - {&__pyx_n_s_six_moves, __pyx_k_six_moves, sizeof(__pyx_k_six_moves), 0, 0, 1, 1}, - {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1}, - {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1}, - {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1}, - {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1}, - {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0}, - {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0}, - {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0}, - {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, - {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1}, - {&__pyx_n_s_subset, __pyx_k_subset, sizeof(__pyx_k_subset), 0, 0, 1, 1}, - {&__pyx_kp_s_subset_is_not_a_subset_of_supers, __pyx_k_subset_is_not_a_subset_of_supers, sizeof(__pyx_k_subset_is_not_a_subset_of_supers), 0, 0, 1, 0}, - {&__pyx_n_s_superset, __pyx_k_superset, sizeof(__pyx_k_superset), 0, 0, 1, 1}, - {&__pyx_n_s_t, __pyx_k_t, sizeof(__pyx_k_t), 0, 0, 1, 1}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0}, - {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0}, - {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0}, - {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1}, - {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1}, - {&__pyx_n_s_vectors, __pyx_k_vectors, sizeof(__pyx_k_vectors), 0, 0, 1, 1}, - {&__pyx_n_s_version, __pyx_k_version, sizeof(__pyx_k_version), 0, 0, 1, 1}, - {&__pyx_n_s_vs, __pyx_k_vs, sizeof(__pyx_k_vs), 0, 0, 1, 1}, - {&__pyx_n_s_within_frac, __pyx_k_within_frac, sizeof(__pyx_k_within_frac), 0, 0, 1, 1}, - {&__pyx_kp_s_wmdrichards_gmail_com, __pyx_k_wmdrichards_gmail_com, sizeof(__pyx_k_wmdrichards_gmail_com), 0, 0, 1, 0}, - {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1}, - {&__pyx_n_s_zip, __pyx_k_zip, sizeof(__pyx_k_zip), 0, 0, 1, 1}, - {0, 0, 0, 0, 0, 0, 0} -}; -static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 45, __pyx_L1_error) - __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(0, 262, __pyx_L1_error) - __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(1, 777, __pyx_L1_error) - __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(1, 959, __pyx_L1_error) - __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) __PYX_ERR(2, 148, __pyx_L1_error) - __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) __PYX_ERR(2, 151, __pyx_L1_error) - __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(2, 2, __pyx_L1_error) - __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) __PYX_ERR(2, 404, __pyx_L1_error) - __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(2, 613, __pyx_L1_error) - __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(2, 832, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - - /* "easyCore/Utils/coord_cython.pyx":262 - * if ok_inner: - * if c_inds[i] >= 0: - * raise ValueError("Something wrong with the inputs, likely duplicates " # <<<<<<<<<<<<<< - * "in superset") - * c_inds[i] = j - */ - __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_Something_wrong_with_the_inputs); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 262, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple_); - __Pyx_GIVEREF(__pyx_tuple_); - - /* "easyCore/Utils/coord_cython.pyx":271 - * - * if not ok_outer: - * raise ValueError("subset is not a subset of superset") # <<<<<<<<<<<<<< - * - * return inds - */ - __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_subset_is_not_a_subset_of_supers); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 271, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__2); - __Pyx_GIVEREF(__pyx_tuple__2); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":777 - * - * if (end - f) - (new_offset - offset[0]) < 15: - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< - * - * if ((child.byteorder == c'>' and little_endian) or - */ - __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(1, 777, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__3); - __Pyx_GIVEREF(__pyx_tuple__3); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":781 - * if ((child.byteorder == c'>' and little_endian) or - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< - * # One could encode it in the format string and have Cython - * # complain instead, BUT: < and > in format strings also imply - */ - __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 781, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__4); - __Pyx_GIVEREF(__pyx_tuple__4); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":801 - * t = child.type_num - * if end - f < 5: - * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< - * - * # Until ticket #99 is fixed, use integers to avoid warnings - */ - __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 801, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__5); - __Pyx_GIVEREF(__pyx_tuple__5); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":959 - * __pyx_import_array() - * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_umath() except -1: - */ - __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_multiarray_failed_to); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 959, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__6); - __Pyx_GIVEREF(__pyx_tuple__6); - - /* "../../../anaconda3/envs/easyCore/lib/python3.8/site-packages/numpy/__init__.pxd":965 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_ufunc() except -1: - */ - __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_umath_failed_to_impor); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(1, 965, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__7); - __Pyx_GIVEREF(__pyx_tuple__7); - - /* "View.MemoryView":133 - * - * if not self.ndim: - * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<< - * - * if itemsize <= 0: - */ - __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(2, 133, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__8); - __Pyx_GIVEREF(__pyx_tuple__8); - - /* "View.MemoryView":136 - * - * if itemsize <= 0: - * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<< - * - * if not isinstance(format, bytes): - */ - __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(2, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__9); - __Pyx_GIVEREF(__pyx_tuple__9); - - /* "View.MemoryView":148 - * - * if not self._shape: - * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<< - * - * - */ - __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(2, 148, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__10); - __Pyx_GIVEREF(__pyx_tuple__10); - - /* "View.MemoryView":176 - * self.data = malloc(self.len) - * if not self.data: - * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<< - * - * if self.dtype_is_object: - */ - __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(2, 176, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__11); - __Pyx_GIVEREF(__pyx_tuple__11); - - /* "View.MemoryView":192 - * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS - * if not (flags & bufmode): - * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<< - * info.buf = self.data - * info.len = self.len - */ - __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(2, 192, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__12); - __Pyx_GIVEREF(__pyx_tuple__12); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(2, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__13); - __Pyx_GIVEREF(__pyx_tuple__13); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__14); - __Pyx_GIVEREF(__pyx_tuple__14); - - /* "View.MemoryView":418 - * def __setitem__(memoryview self, object index, object value): - * if self.view.readonly: - * raise TypeError("Cannot assign to read-only memoryview") # <<<<<<<<<<<<<< - * - * have_slices, index = _unellipsify(index, self.view.ndim) - */ - __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s_Cannot_assign_to_read_only_memor); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(2, 418, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__15); - __Pyx_GIVEREF(__pyx_tuple__15); - - /* "View.MemoryView":495 - * result = struct.unpack(self.view.format, bytesitem) - * except struct.error: - * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<< - * else: - * if len(self.view.format) == 1: - */ - __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(2, 495, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__16); - __Pyx_GIVEREF(__pyx_tuple__16); - - /* "View.MemoryView":520 - * def __getbuffer__(self, Py_buffer *info, int flags): - * if flags & PyBUF_WRITABLE and self.view.readonly: - * raise ValueError("Cannot create writable memory view from read-only memoryview") # <<<<<<<<<<<<<< - * - * if flags & PyBUF_ND: - */ - __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s_Cannot_create_writable_memory_vi); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(2, 520, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__17); - __Pyx_GIVEREF(__pyx_tuple__17); - - /* "View.MemoryView":570 - * if self.view.strides == NULL: - * - * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<< - * - * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) - */ - __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(2, 570, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__18); - __Pyx_GIVEREF(__pyx_tuple__18); - - /* "View.MemoryView":577 - * def suboffsets(self): - * if self.view.suboffsets == NULL: - * return (-1,) * self.view.ndim # <<<<<<<<<<<<<< - * - * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) - */ - __pyx_tuple__19 = PyTuple_New(1); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(2, 577, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__19); - __Pyx_INCREF(__pyx_int_neg_1); - __Pyx_GIVEREF(__pyx_int_neg_1); - PyTuple_SET_ITEM(__pyx_tuple__19, 0, __pyx_int_neg_1); - __Pyx_GIVEREF(__pyx_tuple__19); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(2, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__20); - __Pyx_GIVEREF(__pyx_tuple__20); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_tuple__21 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__21); - __Pyx_GIVEREF(__pyx_tuple__21); - - /* "View.MemoryView":682 - * if item is Ellipsis: - * if not seen_ellipsis: - * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<< - * seen_ellipsis = True - * else: - */ - __pyx_slice__22 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__22)) __PYX_ERR(2, 682, __pyx_L1_error) - __Pyx_GOTREF(__pyx_slice__22); - __Pyx_GIVEREF(__pyx_slice__22); - - /* "View.MemoryView":703 - * for suboffset in suboffsets[:ndim]: - * if suboffset >= 0: - * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<< - * - * - */ - __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(2, 703, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__23); - __Pyx_GIVEREF(__pyx_tuple__23); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(2, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__24); - __Pyx_GIVEREF(__pyx_tuple__24); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(2, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__25); - __Pyx_GIVEREF(__pyx_tuple__25); - - /* "easyCore/Utils/coord_cython.pyx":27 - * - * #create images, 2d array of all length 3 combinations of [-1,0,1] - * r = np.arange(-1, 2, dtype=np.float_) # <<<<<<<<<<<<<< - * arange = r[:, None] * np.array([1, 0, 0])[None, :] - * brange = r[:, None] * np.array([0, 1, 0])[None, :] - */ - __pyx_tuple__31 = PyTuple_Pack(2, __pyx_int_neg_1, __pyx_int_2); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(0, 27, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__31); - __Pyx_GIVEREF(__pyx_tuple__31); - - /* "easyCore/Utils/coord_cython.pyx":28 - * #create images, 2d array of all length 3 combinations of [-1,0,1] - * r = np.arange(-1, 2, dtype=np.float_) - * arange = r[:, None] * np.array([1, 0, 0])[None, :] # <<<<<<<<<<<<<< - * brange = r[:, None] * np.array([0, 1, 0])[None, :] - * crange = r[:, None] * np.array([0, 0, 1])[None, :] - */ - __pyx_tuple__32 = PyTuple_Pack(2, __pyx_slice__22, Py_None); if (unlikely(!__pyx_tuple__32)) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__32); - __Pyx_GIVEREF(__pyx_tuple__32); - __pyx_tuple__33 = PyTuple_Pack(2, Py_None, __pyx_slice__22); if (unlikely(!__pyx_tuple__33)) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__33); - __Pyx_GIVEREF(__pyx_tuple__33); - - /* "easyCore/Utils/coord_cython.pyx":31 - * brange = r[:, None] * np.array([0, 1, 0])[None, :] - * crange = r[:, None] * np.array([0, 0, 1])[None, :] - * images_t = arange[:, None, None] + brange[None, :, None] + \ # <<<<<<<<<<<<<< - * crange[None, None, :] - * images = images_t.reshape((27, 3)) - */ - __pyx_tuple__34 = PyTuple_Pack(3, __pyx_slice__22, Py_None, Py_None); if (unlikely(!__pyx_tuple__34)) __PYX_ERR(0, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__34); - __Pyx_GIVEREF(__pyx_tuple__34); - __pyx_tuple__35 = PyTuple_Pack(3, Py_None, __pyx_slice__22, Py_None); if (unlikely(!__pyx_tuple__35)) __PYX_ERR(0, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__35); - __Pyx_GIVEREF(__pyx_tuple__35); - - /* "easyCore/Utils/coord_cython.pyx":32 - * crange = r[:, None] * np.array([0, 0, 1])[None, :] - * images_t = arange[:, None, None] + brange[None, :, None] + \ - * crange[None, None, :] # <<<<<<<<<<<<<< - * images = images_t.reshape((27, 3)) - * - */ - __pyx_tuple__36 = PyTuple_Pack(3, Py_None, Py_None, __pyx_slice__22); if (unlikely(!__pyx_tuple__36)) __PYX_ERR(0, 32, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__36); - __Pyx_GIVEREF(__pyx_tuple__36); - - /* "easyCore/Utils/coord_cython.pyx":33 - * images_t = arange[:, None, None] + brange[None, :, None] + \ - * crange[None, None, :] - * images = images_t.reshape((27, 3)) # <<<<<<<<<<<<<< - * - * cdef np.float_t[:, ::1] images_view = images - */ - __pyx_tuple__37 = PyTuple_Pack(2, __pyx_int_27, __pyx_int_3); if (unlikely(!__pyx_tuple__37)) __PYX_ERR(0, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__37); - __Pyx_GIVEREF(__pyx_tuple__37); - __pyx_tuple__38 = PyTuple_Pack(1, __pyx_tuple__37); if (unlikely(!__pyx_tuple__38)) __PYX_ERR(0, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__38); - __Pyx_GIVEREF(__pyx_tuple__38); - - /* "easyCore/Utils/coord_cython.pyx":70 - * @cython.wraparound(False) - * @cython.initializedcheck(False) - * def pbc_shortest_vectors(lattice, fcoords1, fcoords2, mask=None, return_d2=False, lll_frac_tol=None): # <<<<<<<<<<<<<< - * """ - * Returns the shortest vectors between two lists of coordinates taking into - */ - __pyx_tuple__39 = PyTuple_Pack(37, __pyx_n_s_lattice, __pyx_n_s_fcoords1, __pyx_n_s_fcoords2, __pyx_n_s_mask, __pyx_n_s_return_d2, __pyx_n_s_lll_frac_tol, __pyx_n_s_lat, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_l, __pyx_n_s_I, __pyx_n_s_J, __pyx_n_s_bestK, __pyx_n_s_fc1, __pyx_n_s_fc2, __pyx_n_s_cart_f1, __pyx_n_s_cart_f2, __pyx_n_s_cart_im, __pyx_n_s_has_mask, __pyx_n_s_m, __pyx_n_s_has_ftol, __pyx_n_s_ftol, __pyx_n_s_vectors, __pyx_n_s_d2, __pyx_n_s_vs, __pyx_n_s_ds, __pyx_n_s_best, __pyx_n_s_d, __pyx_n_s_inc_d, __pyx_n_s_da, __pyx_n_s_db, __pyx_n_s_dc, __pyx_n_s_fdist, __pyx_n_s_within_frac, __pyx_n_s_pre_im, __pyx_n_s_bestk); if (unlikely(!__pyx_tuple__39)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__39); - __Pyx_GIVEREF(__pyx_tuple__39); - __pyx_codeobj__40 = (PyObject*)__Pyx_PyCode_New(6, 0, 37, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__39, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_easyCore_Utils_coord_cython_pyx, __pyx_n_s_pbc_shortest_vectors, 70, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__40)) __PYX_ERR(0, 70, __pyx_L1_error) - - /* "easyCore/Utils/coord_cython.pyx":181 - * @cython.wraparound(False) - * @cython.initializedcheck(False) - * def is_coord_subset_pbc(subset, superset, atol, mask): # <<<<<<<<<<<<<< - * """ - * Tests if all fractional coords in subset are contained in superset. - */ - __pyx_tuple__41 = PyTuple_Pack(15, __pyx_n_s_subset, __pyx_n_s_superset, __pyx_n_s_atol, __pyx_n_s_mask, __pyx_n_s_fc1, __pyx_n_s_fc2, __pyx_n_s_t, __pyx_n_s_m, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k, __pyx_n_s_I, __pyx_n_s_J, __pyx_n_s_d, __pyx_n_s_ok); if (unlikely(!__pyx_tuple__41)) __PYX_ERR(0, 181, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__41); - __Pyx_GIVEREF(__pyx_tuple__41); - __pyx_codeobj__42 = (PyObject*)__Pyx_PyCode_New(4, 0, 15, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__41, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_easyCore_Utils_coord_cython_pyx, __pyx_n_s_is_coord_subset_pbc, 181, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__42)) __PYX_ERR(0, 181, __pyx_L1_error) - - /* "easyCore/Utils/coord_cython.pyx":226 - * @cython.wraparound(False) - * @cython.initializedcheck(False) - * def coord_list_mapping_pbc(subset, superset, atol=1e-8): # <<<<<<<<<<<<<< - * """ - * Gives the index mapping from a subset to a superset. - */ - __pyx_tuple__43 = PyTuple_Pack(16, __pyx_n_s_subset, __pyx_n_s_superset, __pyx_n_s_atol, __pyx_n_s_inds, __pyx_n_s_fc1, __pyx_n_s_fc2, __pyx_n_s_t, __pyx_n_s_c_inds, __pyx_n_s_d, __pyx_n_s_ok_inner, __pyx_n_s_ok_outer, __pyx_n_s_I, __pyx_n_s_J, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k); if (unlikely(!__pyx_tuple__43)) __PYX_ERR(0, 226, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__43); - __Pyx_GIVEREF(__pyx_tuple__43); - __pyx_codeobj__44 = (PyObject*)__Pyx_PyCode_New(3, 0, 16, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__43, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_easyCore_Utils_coord_cython_pyx, __pyx_n_s_coord_list_mapping_pbc, 226, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__44)) __PYX_ERR(0, 226, __pyx_L1_error) - - /* "View.MemoryView":286 - * return self.name - * - * cdef generic = Enum("") # <<<<<<<<<<<<<< - * cdef strided = Enum("") # default - * cdef indirect = Enum("") - */ - __pyx_tuple__45 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__45)) __PYX_ERR(2, 286, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__45); - __Pyx_GIVEREF(__pyx_tuple__45); - - /* "View.MemoryView":287 - * - * cdef generic = Enum("") - * cdef strided = Enum("") # default # <<<<<<<<<<<<<< - * cdef indirect = Enum("") - * - */ - __pyx_tuple__46 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__46)) __PYX_ERR(2, 287, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__46); - __Pyx_GIVEREF(__pyx_tuple__46); - - /* "View.MemoryView":288 - * cdef generic = Enum("") - * cdef strided = Enum("") # default - * cdef indirect = Enum("") # <<<<<<<<<<<<<< - * - * - */ - __pyx_tuple__47 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__47)) __PYX_ERR(2, 288, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__47); - __Pyx_GIVEREF(__pyx_tuple__47); - - /* "View.MemoryView":291 - * - * - * cdef contiguous = Enum("") # <<<<<<<<<<<<<< - * cdef indirect_contiguous = Enum("") - * - */ - __pyx_tuple__48 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__48)) __PYX_ERR(2, 291, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__48); - __Pyx_GIVEREF(__pyx_tuple__48); - - /* "View.MemoryView":292 - * - * cdef contiguous = Enum("") - * cdef indirect_contiguous = Enum("") # <<<<<<<<<<<<<< - * - * - */ - __pyx_tuple__49 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__49)) __PYX_ERR(2, 292, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__49); - __Pyx_GIVEREF(__pyx_tuple__49); - - /* "(tree fragment)":1 - * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - __pyx_tuple__50 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__50)) __PYX_ERR(2, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__50); - __Pyx_GIVEREF(__pyx_tuple__50); - __pyx_codeobj__51 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__50, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_Enum, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__51)) __PYX_ERR(2, 1, __pyx_L1_error) - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { - if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - __pyx_float_1eneg_8 = PyFloat_FromDouble(1e-8); if (unlikely(!__pyx_float_1eneg_8)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_27 = PyInt_FromLong(27); if (unlikely(!__pyx_int_27)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_184977713 = PyInt_FromLong(184977713L); if (unlikely(!__pyx_int_184977713)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) __PYX_ERR(0, 1, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ - -static int __Pyx_modinit_global_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); - /*--- Global init code ---*/ - generic = Py_None; Py_INCREF(Py_None); - strided = Py_None; Py_INCREF(Py_None); - indirect = Py_None; Py_INCREF(Py_None); - contiguous = Py_None; Py_INCREF(Py_None); - indirect_contiguous = Py_None; Py_INCREF(Py_None); - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); - /*--- Variable export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); - /*--- Function export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_init_code(void) { - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); - /*--- Type init code ---*/ - __pyx_vtabptr_array = &__pyx_vtable_array; - __pyx_vtable_array.get_memview = (PyObject *(*)(struct __pyx_array_obj *))__pyx_array_get_memview; - if (PyType_Ready(&__pyx_type___pyx_array) < 0) __PYX_ERR(2, 105, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type___pyx_array.tp_print = 0; - #endif - if (__Pyx_SetVtable(__pyx_type___pyx_array.tp_dict, __pyx_vtabptr_array) < 0) __PYX_ERR(2, 105, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type___pyx_array) < 0) __PYX_ERR(2, 105, __pyx_L1_error) - __pyx_array_type = &__pyx_type___pyx_array; - if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) __PYX_ERR(2, 279, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type___pyx_MemviewEnum.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type___pyx_MemviewEnum.tp_dictoffset && __pyx_type___pyx_MemviewEnum.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type___pyx_MemviewEnum.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (__Pyx_setup_reduce((PyObject*)&__pyx_type___pyx_MemviewEnum) < 0) __PYX_ERR(2, 279, __pyx_L1_error) - __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum; - __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview; - __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer; - __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice; - __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment; - __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar; - __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed; - __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object; - __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object; - if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) __PYX_ERR(2, 330, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type___pyx_memoryview.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type___pyx_memoryview.tp_dictoffset && __pyx_type___pyx_memoryview.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type___pyx_memoryview.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) __PYX_ERR(2, 330, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type___pyx_memoryview) < 0) __PYX_ERR(2, 330, __pyx_L1_error) - __pyx_memoryview_type = &__pyx_type___pyx_memoryview; - __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice; - __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview; - __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object; - __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object; - __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type; - if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) __PYX_ERR(2, 965, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type___pyx_memoryviewslice.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type___pyx_memoryviewslice.tp_dictoffset && __pyx_type___pyx_memoryviewslice.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type___pyx_memoryviewslice.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) __PYX_ERR(2, 965, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type___pyx_memoryviewslice) < 0) __PYX_ERR(2, 965, __pyx_L1_error) - __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_type_import_code(void) { - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); - /*--- Type import code ---*/ - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", - #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyTypeObject), - #else - sizeof(PyHeapTypeObject), - #endif - __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(3, 9, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyImport_ImportModule("numpy"); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 207, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_5numpy_dtype = __Pyx_ImportType(__pyx_t_1, "numpy", "dtype", sizeof(PyArray_Descr), __Pyx_ImportType_CheckSize_Ignore); - if (!__pyx_ptype_5numpy_dtype) __PYX_ERR(1, 207, __pyx_L1_error) - __pyx_ptype_5numpy_flatiter = __Pyx_ImportType(__pyx_t_1, "numpy", "flatiter", sizeof(PyArrayIterObject), __Pyx_ImportType_CheckSize_Ignore); - if (!__pyx_ptype_5numpy_flatiter) __PYX_ERR(1, 230, __pyx_L1_error) - __pyx_ptype_5numpy_broadcast = __Pyx_ImportType(__pyx_t_1, "numpy", "broadcast", sizeof(PyArrayMultiIterObject), __Pyx_ImportType_CheckSize_Ignore); - if (!__pyx_ptype_5numpy_broadcast) __PYX_ERR(1, 234, __pyx_L1_error) - __pyx_ptype_5numpy_ndarray = __Pyx_ImportType(__pyx_t_1, "numpy", "ndarray", sizeof(PyArrayObject), __Pyx_ImportType_CheckSize_Ignore); - if (!__pyx_ptype_5numpy_ndarray) __PYX_ERR(1, 246, __pyx_L1_error) - __pyx_ptype_5numpy_ufunc = __Pyx_ImportType(__pyx_t_1, "numpy", "ufunc", sizeof(PyUFuncObject), __Pyx_ImportType_CheckSize_Ignore); - if (!__pyx_ptype_5numpy_ufunc) __PYX_ERR(1, 839, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_variable_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); - /*--- Variable import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); - /*--- Function import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - - -#ifndef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#elif PY_MAJOR_VERSION < 3 -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" void -#else -#define __Pyx_PyMODINIT_FUNC void -#endif -#else -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * -#else -#define __Pyx_PyMODINIT_FUNC PyObject * -#endif -#endif - - -#if PY_MAJOR_VERSION < 3 -__Pyx_PyMODINIT_FUNC initcoord_cython(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC initcoord_cython(void) -#else -__Pyx_PyMODINIT_FUNC PyInit_coord_cython(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC PyInit_coord_cython(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { - #if PY_VERSION_HEX >= 0x030700A1 - static PY_INT64_T main_interpreter_id = -1; - PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); - if (main_interpreter_id == -1) { - main_interpreter_id = current_id; - return (unlikely(current_id == -1)) ? -1 : 0; - } else if (unlikely(main_interpreter_id != current_id)) - #else - static PyInterpreterState *main_interpreter = NULL; - PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; - if (!main_interpreter) { - main_interpreter = current_interpreter; - } else if (unlikely(main_interpreter != current_interpreter)) - #endif - { - PyErr_SetString( - PyExc_ImportError, - "Interpreter change detected - this module can only be loaded into one interpreter per process."); - return -1; - } - return 0; -} -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - if (allow_none || value != Py_None) { - result = PyDict_SetItemString(moddict, to_name, value); - } - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - if (__Pyx_check_single_interpreter()) - return NULL; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - - -static CYTHON_SMALL_CODE int __pyx_pymod_exec_coord_cython(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - __Pyx_memviewslice __pyx_t_5 = { 0, 0, { 0 }, { 0 }, { 0 } }; - static PyThread_type_lock __pyx_t_6[8]; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m) { - if (__pyx_m == __pyx_pyinit_module) return 0; - PyErr_SetString(PyExc_RuntimeError, "Module 'coord_cython' has already been imported. Re-initialisation is not supported."); - return -1; - } - #elif PY_MAJOR_VERSION >= 3 - if (__pyx_m) return __Pyx_NewRef(__pyx_m); - #endif - #if CYTHON_REFNANNY -__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); -if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); -} -#endif - __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_coord_cython(void)", 0); - if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pxy_PyFrame_Initialize_Offsets - __Pxy_PyFrame_Initialize_Offsets(); - #endif - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - #ifdef WITH_THREAD /* Python build with threading support? */ - PyEval_InitThreads(); - #endif - #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("coord_cython", __pyx_methods, __pyx_k_Utilities_for_manipulating_coor, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - #endif - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_b); - __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_cython_runtime); - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - if (__pyx_module_is_main_easyCore__Utils__coord_cython) { - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name_2, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - } - #if PY_MAJOR_VERSION >= 3 - { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "easyCore.Utils.coord_cython")) { - if (unlikely(PyDict_SetItemString(modules, "easyCore.Utils.coord_cython", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - } - } - #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Global type/function init code ---*/ - (void)__Pyx_modinit_global_init_code(); - (void)__Pyx_modinit_variable_export_code(); - (void)__Pyx_modinit_function_export_code(); - if (unlikely(__Pyx_modinit_type_init_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - if (unlikely(__Pyx_modinit_type_import_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - (void)__Pyx_modinit_variable_import_code(); - (void)__Pyx_modinit_function_import_code(); - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "easyCore/Utils/coord_cython.pyx":10 - * """ - * - * from six.moves import zip # <<<<<<<<<<<<<< - * - * __author__ = "Will Richards" - */ - __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 10, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_s_zip); - __Pyx_GIVEREF(__pyx_n_s_zip); - PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_zip); - __pyx_t_2 = __Pyx_Import(__pyx_n_s_six_moves, __pyx_t_1, -1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 10, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_zip); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 10, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_zip, __pyx_t_1) < 0) __PYX_ERR(0, 10, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "easyCore/Utils/coord_cython.pyx":12 - * from six.moves import zip - * - * __author__ = "Will Richards" # <<<<<<<<<<<<<< - * __copyright__ = "Copyright 2011, The Materials Project" - * __version__ = "1.0" - */ - if (PyDict_SetItem(__pyx_d, __pyx_n_s_author, __pyx_kp_s_Will_Richards) < 0) __PYX_ERR(0, 12, __pyx_L1_error) - - /* "easyCore/Utils/coord_cython.pyx":13 - * - * __author__ = "Will Richards" - * __copyright__ = "Copyright 2011, The Materials Project" # <<<<<<<<<<<<<< - * __version__ = "1.0" - * __maintainer__ = "Will Richards" - */ - if (PyDict_SetItem(__pyx_d, __pyx_n_s_copyright, __pyx_kp_s_Copyright_2011_The_Materials_Pro) < 0) __PYX_ERR(0, 13, __pyx_L1_error) - - /* "easyCore/Utils/coord_cython.pyx":14 - * __author__ = "Will Richards" - * __copyright__ = "Copyright 2011, The Materials Project" - * __version__ = "1.0" # <<<<<<<<<<<<<< - * __maintainer__ = "Will Richards" - * __email__ = "wmdrichards@gmail.com" - */ - if (PyDict_SetItem(__pyx_d, __pyx_n_s_version, __pyx_kp_s_1_0) < 0) __PYX_ERR(0, 14, __pyx_L1_error) - - /* "easyCore/Utils/coord_cython.pyx":15 - * __copyright__ = "Copyright 2011, The Materials Project" - * __version__ = "1.0" - * __maintainer__ = "Will Richards" # <<<<<<<<<<<<<< - * __email__ = "wmdrichards@gmail.com" - * __date__ = "Nov 27, 2011" - */ - if (PyDict_SetItem(__pyx_d, __pyx_n_s_maintainer, __pyx_kp_s_Will_Richards) < 0) __PYX_ERR(0, 15, __pyx_L1_error) - - /* "easyCore/Utils/coord_cython.pyx":16 - * __version__ = "1.0" - * __maintainer__ = "Will Richards" - * __email__ = "wmdrichards@gmail.com" # <<<<<<<<<<<<<< - * __date__ = "Nov 27, 2011" - * - */ - if (PyDict_SetItem(__pyx_d, __pyx_n_s_email, __pyx_kp_s_wmdrichards_gmail_com) < 0) __PYX_ERR(0, 16, __pyx_L1_error) - - /* "easyCore/Utils/coord_cython.pyx":17 - * __maintainer__ = "Will Richards" - * __email__ = "wmdrichards@gmail.com" - * __date__ = "Nov 27, 2011" # <<<<<<<<<<<<<< - * - * import numpy as np - */ - if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_Nov_27_2011) < 0) __PYX_ERR(0, 17, __pyx_L1_error) - - /* "easyCore/Utils/coord_cython.pyx":19 - * __date__ = "Nov 27, 2011" - * - * import numpy as np # <<<<<<<<<<<<<< - * - * from libc.stdlib cimport malloc, free - */ - __pyx_t_2 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_2) < 0) __PYX_ERR(0, 19, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "easyCore/Utils/coord_cython.pyx":27 - * - * #create images, 2d array of all length 3 combinations of [-1,0,1] - * r = np.arange(-1, 2, dtype=np.float_) # <<<<<<<<<<<<<< - * arange = r[:, None] * np.array([1, 0, 0])[None, :] - * brange = r[:, None] * np.array([0, 1, 0])[None, :] - */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 27, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_arange); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 27, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 27, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 27, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_float); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 27, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_4) < 0) __PYX_ERR(0, 27, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__31, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 27, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (PyDict_SetItem(__pyx_d, __pyx_n_s_r, __pyx_t_4) < 0) __PYX_ERR(0, 27, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "easyCore/Utils/coord_cython.pyx":28 - * #create images, 2d array of all length 3 combinations of [-1,0,1] - * r = np.arange(-1, 2, dtype=np.float_) - * arange = r[:, None] * np.array([1, 0, 0])[None, :] # <<<<<<<<<<<<<< - * brange = r[:, None] * np.array([0, 1, 0])[None, :] - * crange = r[:, None] * np.array([0, 0, 1])[None, :] - */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_r); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_4, __pyx_tuple__32); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_array); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = PyList_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_INCREF(__pyx_int_1); - __Pyx_GIVEREF(__pyx_int_1); - PyList_SET_ITEM(__pyx_t_4, 0, __pyx_int_1); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyList_SET_ITEM(__pyx_t_4, 1, __pyx_int_0); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyList_SET_ITEM(__pyx_t_4, 2, __pyx_int_0); - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_tuple__33); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = PyNumber_Multiply(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (PyDict_SetItem(__pyx_d, __pyx_n_s_arange, __pyx_t_3) < 0) __PYX_ERR(0, 28, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "easyCore/Utils/coord_cython.pyx":29 - * r = np.arange(-1, 2, dtype=np.float_) - * arange = r[:, None] * np.array([1, 0, 0])[None, :] - * brange = r[:, None] * np.array([0, 1, 0])[None, :] # <<<<<<<<<<<<<< - * crange = r[:, None] * np.array([0, 0, 1])[None, :] - * images_t = arange[:, None, None] + brange[None, :, None] + \ - */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_r); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_tuple__32); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = PyList_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyList_SET_ITEM(__pyx_t_3, 0, __pyx_int_0); - __Pyx_INCREF(__pyx_int_1); - __Pyx_GIVEREF(__pyx_int_1); - PyList_SET_ITEM(__pyx_t_3, 1, __pyx_int_1); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyList_SET_ITEM(__pyx_t_3, 2, __pyx_int_0); - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_tuple__33); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyNumber_Multiply(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 29, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (PyDict_SetItem(__pyx_d, __pyx_n_s_brange, __pyx_t_1) < 0) __PYX_ERR(0, 29, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "easyCore/Utils/coord_cython.pyx":30 - * arange = r[:, None] * np.array([1, 0, 0])[None, :] - * brange = r[:, None] * np.array([0, 1, 0])[None, :] - * crange = r[:, None] * np.array([0, 0, 1])[None, :] # <<<<<<<<<<<<<< - * images_t = arange[:, None, None] + brange[None, :, None] + \ - * crange[None, None, :] - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_r); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_tuple__32); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyList_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyList_SET_ITEM(__pyx_t_1, 0, __pyx_int_0); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyList_SET_ITEM(__pyx_t_1, 1, __pyx_int_0); - __Pyx_INCREF(__pyx_int_1); - __Pyx_GIVEREF(__pyx_int_1); - PyList_SET_ITEM(__pyx_t_1, 2, __pyx_int_1); - __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_tuple__33); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = PyNumber_Multiply(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (PyDict_SetItem(__pyx_d, __pyx_n_s_crange, __pyx_t_2) < 0) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "easyCore/Utils/coord_cython.pyx":31 - * brange = r[:, None] * np.array([0, 1, 0])[None, :] - * crange = r[:, None] * np.array([0, 0, 1])[None, :] - * images_t = arange[:, None, None] + brange[None, :, None] + \ # <<<<<<<<<<<<<< - * crange[None, None, :] - * images = images_t.reshape((27, 3)) - */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_arange); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_tuple__34); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_brange); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_tuple__35); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "easyCore/Utils/coord_cython.pyx":32 - * crange = r[:, None] * np.array([0, 0, 1])[None, :] - * images_t = arange[:, None, None] + brange[None, :, None] + \ - * crange[None, None, :] # <<<<<<<<<<<<<< - * images = images_t.reshape((27, 3)) - * - */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_crange); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 32, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_tuple__36); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 32, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "easyCore/Utils/coord_cython.pyx":31 - * brange = r[:, None] * np.array([0, 1, 0])[None, :] - * crange = r[:, None] * np.array([0, 0, 1])[None, :] - * images_t = arange[:, None, None] + brange[None, :, None] + \ # <<<<<<<<<<<<<< - * crange[None, None, :] - * images = images_t.reshape((27, 3)) - */ - __pyx_t_3 = PyNumber_Add(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (PyDict_SetItem(__pyx_d, __pyx_n_s_images_t, __pyx_t_3) < 0) __PYX_ERR(0, 31, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "easyCore/Utils/coord_cython.pyx":33 - * images_t = arange[:, None, None] + brange[None, :, None] + \ - * crange[None, None, :] - * images = images_t.reshape((27, 3)) # <<<<<<<<<<<<<< - * - * cdef np.float_t[:, ::1] images_view = images - */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_images_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_reshape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__38, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (PyDict_SetItem(__pyx_d, __pyx_n_s_images, __pyx_t_3) < 0) __PYX_ERR(0, 33, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "easyCore/Utils/coord_cython.pyx":35 - * images = images_t.reshape((27, 3)) - * - * cdef np.float_t[:, ::1] images_view = images # <<<<<<<<<<<<<< - * - * @cython.boundscheck(False) - */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_images); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_float_t(__pyx_t_3, PyBUF_WRITABLE); if (unlikely(!__pyx_t_5.memview)) __PYX_ERR(0, 35, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_XDEC_MEMVIEW(&__pyx_v_8easyCore_5Utils_12coord_cython_images_view, 1); - __pyx_v_8easyCore_5Utils_12coord_cython_images_view = __pyx_t_5; - __pyx_t_5.memview = NULL; - __pyx_t_5.data = NULL; - - /* "easyCore/Utils/coord_cython.pyx":70 - * @cython.wraparound(False) - * @cython.initializedcheck(False) - * def pbc_shortest_vectors(lattice, fcoords1, fcoords2, mask=None, return_d2=False, lll_frac_tol=None): # <<<<<<<<<<<<<< - * """ - * Returns the shortest vectors between two lists of coordinates taking into - */ - __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_8easyCore_5Utils_12coord_cython_1pbc_shortest_vectors, NULL, __pyx_n_s_easyCore_Utils_coord_cython); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_pbc_shortest_vectors, __pyx_t_3) < 0) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "easyCore/Utils/coord_cython.pyx":181 - * @cython.wraparound(False) - * @cython.initializedcheck(False) - * def is_coord_subset_pbc(subset, superset, atol, mask): # <<<<<<<<<<<<<< - * """ - * Tests if all fractional coords in subset are contained in superset. - */ - __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_8easyCore_5Utils_12coord_cython_3is_coord_subset_pbc, NULL, __pyx_n_s_easyCore_Utils_coord_cython); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 181, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_is_coord_subset_pbc, __pyx_t_3) < 0) __PYX_ERR(0, 181, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "easyCore/Utils/coord_cython.pyx":226 - * @cython.wraparound(False) - * @cython.initializedcheck(False) - * def coord_list_mapping_pbc(subset, superset, atol=1e-8): # <<<<<<<<<<<<<< - * """ - * Gives the index mapping from a subset to a superset. - */ - __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_8easyCore_5Utils_12coord_cython_5coord_list_mapping_pbc, NULL, __pyx_n_s_easyCore_Utils_coord_cython); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 226, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_coord_list_mapping_pbc, __pyx_t_3) < 0) __PYX_ERR(0, 226, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "easyCore/Utils/coord_cython.pyx":1 - * # coding: utf-8 # <<<<<<<<<<<<<< - * - * #from __future__ import division, unicode_literals - */ - __pyx_t_3 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_3) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "View.MemoryView":209 - * info.obj = self - * - * __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<< - * - * def __dealloc__(array self): - */ - __pyx_t_3 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), ((char *)"getbuffer(obj, view, flags)")); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 209, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem((PyObject *)__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_3) < 0) __PYX_ERR(2, 209, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - PyType_Modified(__pyx_array_type); - - /* "View.MemoryView":286 - * return self.name - * - * cdef generic = Enum("") # <<<<<<<<<<<<<< - * cdef strided = Enum("") # default - * cdef indirect = Enum("") - */ - __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__45, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 286, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_XGOTREF(generic); - __Pyx_DECREF_SET(generic, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":287 - * - * cdef generic = Enum("") - * cdef strided = Enum("") # default # <<<<<<<<<<<<<< - * cdef indirect = Enum("") - * - */ - __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__46, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 287, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_XGOTREF(strided); - __Pyx_DECREF_SET(strided, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":288 - * cdef generic = Enum("") - * cdef strided = Enum("") # default - * cdef indirect = Enum("") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__47, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 288, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_XGOTREF(indirect); - __Pyx_DECREF_SET(indirect, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":291 - * - * - * cdef contiguous = Enum("") # <<<<<<<<<<<<<< - * cdef indirect_contiguous = Enum("") - * - */ - __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__48, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 291, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_XGOTREF(contiguous); - __Pyx_DECREF_SET(contiguous, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":292 - * - * cdef contiguous = Enum("") - * cdef indirect_contiguous = Enum("") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__49, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 292, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_XGOTREF(indirect_contiguous); - __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - __pyx_t_3 = 0; - - /* "View.MemoryView":316 - * - * DEF THREAD_LOCKS_PREALLOCATED = 8 - * cdef int __pyx_memoryview_thread_locks_used = 0 # <<<<<<<<<<<<<< - * cdef PyThread_type_lock[THREAD_LOCKS_PREALLOCATED] __pyx_memoryview_thread_locks = [ - * PyThread_allocate_lock(), - */ - __pyx_memoryview_thread_locks_used = 0; - - /* "View.MemoryView":317 - * DEF THREAD_LOCKS_PREALLOCATED = 8 - * cdef int __pyx_memoryview_thread_locks_used = 0 - * cdef PyThread_type_lock[THREAD_LOCKS_PREALLOCATED] __pyx_memoryview_thread_locks = [ # <<<<<<<<<<<<<< - * PyThread_allocate_lock(), - * PyThread_allocate_lock(), - */ - __pyx_t_6[0] = PyThread_allocate_lock(); - __pyx_t_6[1] = PyThread_allocate_lock(); - __pyx_t_6[2] = PyThread_allocate_lock(); - __pyx_t_6[3] = PyThread_allocate_lock(); - __pyx_t_6[4] = PyThread_allocate_lock(); - __pyx_t_6[5] = PyThread_allocate_lock(); - __pyx_t_6[6] = PyThread_allocate_lock(); - __pyx_t_6[7] = PyThread_allocate_lock(); - memcpy(&(__pyx_memoryview_thread_locks[0]), __pyx_t_6, sizeof(__pyx_memoryview_thread_locks[0]) * (8)); - - /* "View.MemoryView":549 - * info.obj = self - * - * __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_3 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), ((char *)"getbuffer(obj, view, flags)")); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 549, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem((PyObject *)__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_3) < 0) __PYX_ERR(2, 549, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - PyType_Modified(__pyx_memoryview_type); - - /* "View.MemoryView":995 - * return self.from_object - * - * __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_3 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), ((char *)"getbuffer(obj, view, flags)")); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 995, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem((PyObject *)__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_3) < 0) __PYX_ERR(2, 995, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - PyType_Modified(__pyx_memoryviewslice_type); - - /* "(tree fragment)":1 - * def __pyx_unpickle_Enum(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< - * cdef object __pyx_PickleError - * cdef object __pyx_result - */ - __pyx_t_3 = PyCFunction_NewEx(&__pyx_mdef_15View_dot_MemoryView_1__pyx_unpickle_Enum, NULL, __pyx_n_s_View_MemoryView); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_Enum, __pyx_t_3) < 0) __PYX_ERR(2, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "BufferFormatFromTypeInfo":1463 - * - * @cname('__pyx_format_from_typeinfo') - * cdef bytes format_from_typeinfo(__Pyx_TypeInfo *type): # <<<<<<<<<<<<<< - * cdef __Pyx_StructField *field - * cdef __pyx_typeinfo_string fmt - */ - - /*--- Wrapped vars code ---*/ - - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __PYX_XDEC_MEMVIEW(&__pyx_t_5, 1); - if (__pyx_m) { - if (__pyx_d) { - __Pyx_AddTraceback("init easyCore.Utils.coord_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); - } - Py_CLEAR(__pyx_m); - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init easyCore.Utils.coord_cython"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; - #endif -} - -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule(modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, "RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif - -/* PyObjectGetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); -#endif - return PyObject_GetAttr(obj, attr_name); -} -#endif - -/* GetBuiltinName */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name) { - PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); - if (unlikely(!result)) { - PyErr_Format(PyExc_NameError, -#if PY_MAJOR_VERSION >= 3 - "name '%U' is not defined", name); -#else - "name '%.200s' is not defined", PyString_AS_STRING(name)); -#endif - } - return result; -} - -/* None */ -static CYTHON_INLINE __pyx_t_5numpy_float_t __Pyx_mod___pyx_t_5numpy_float_t(__pyx_t_5numpy_float_t a, __pyx_t_5numpy_float_t b) { - __pyx_t_5numpy_float_t r = fmod(a, b); - r += ((r != 0) & ((r < 0) ^ (b < 0))) * b; - return r; -} - -/* RaiseArgTupleInvalid */ -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *more_or_less; - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", - func_name, more_or_less, num_expected, - (num_expected == 1) ? "" : "s", num_found); -} - -/* RaiseDoubleKeywords */ -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, - PyObject* kw_name) -{ - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION >= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif -} - -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - while (PyDict_Next(kwds, &pos, &key, &value)) { - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; - continue; - } - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - if ((**argname == key) || ( - (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) - && _PyString_Eq(**argname, key))) { - goto arg_passed_twice; - } - argname++; - } - } - } else - #endif - if (likely(PyUnicode_Check(key))) { - while (*name) { - int cmp = (**name == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**name, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - int cmp = (**argname == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**argname, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) goto arg_passed_twice; - argname++; - } - } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - return -1; -} - -/* PyDictVersioning */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { -#if CYTHON_COMPILING_IN_CPYTHON - dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); -#else - dictptr = _PyObject_GetDictPtr(obj); -#endif - } - return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; -} -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); -} -#endif - -/* GetModuleGlobalName */ -#if CYTHON_USE_DICT_VERSIONS -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) -#else -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) -#endif -{ - PyObject *result; -#if !CYTHON_AVOID_BORROWED_REFS -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 - result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } else if (unlikely(PyErr_Occurred())) { - return NULL; - } -#else - result = PyDict_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } -#endif -#else - result = PyObject_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } - PyErr_Clear(); -#endif - return __Pyx_GetBuiltinName(name); -} - -/* PyFunctionFastCall */ -#if CYTHON_FAST_PYCALL -static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, - PyObject *globals) { - PyFrameObject *f; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject **fastlocals; - Py_ssize_t i; - PyObject *result; - assert(globals != NULL); - /* XXX Perhaps we should create a specialized - PyFrame_New() that doesn't take locals, but does - take builtins without sanity checking them. - */ - assert(tstate != NULL); - f = PyFrame_New(tstate, co, globals, NULL); - if (f == NULL) { - return NULL; - } - fastlocals = __Pyx_PyFrame_GetLocalsplus(f); - for (i = 0; i < na; i++) { - Py_INCREF(*args); - fastlocals[i] = *args++; - } - result = PyEval_EvalFrameEx(f,0); - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - return result; -} -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *closure; -#if PY_MAJOR_VERSION >= 3 - PyObject *kwdefs; -#endif - PyObject *kwtuple, **k; - PyObject **d; - Py_ssize_t nd; - Py_ssize_t nk; - PyObject *result; - assert(kwargs == NULL || PyDict_Check(kwargs)); - nk = kwargs ? PyDict_Size(kwargs) : 0; - if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { - return NULL; - } - if ( -#if PY_MAJOR_VERSION >= 3 - co->co_kwonlyargcount == 0 && -#endif - likely(kwargs == NULL || nk == 0) && - co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { - result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); - goto done; - } - else if (nargs == 0 && argdefs != NULL - && co->co_argcount == Py_SIZE(argdefs)) { - /* function called with no arguments, but all parameters have - a default value: use default values as arguments .*/ - args = &PyTuple_GET_ITEM(argdefs, 0); - result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); - goto done; - } - } - if (kwargs != NULL) { - Py_ssize_t pos, i; - kwtuple = PyTuple_New(2 * nk); - if (kwtuple == NULL) { - result = NULL; - goto done; - } - k = &PyTuple_GET_ITEM(kwtuple, 0); - pos = i = 0; - while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { - Py_INCREF(k[i]); - Py_INCREF(k[i+1]); - i += 2; - } - nk = i / 2; - } - else { - kwtuple = NULL; - k = NULL; - } - closure = PyFunction_GET_CLOSURE(func); -#if PY_MAJOR_VERSION >= 3 - kwdefs = PyFunction_GET_KW_DEFAULTS(func); -#endif - if (argdefs != NULL) { - d = &PyTuple_GET_ITEM(argdefs, 0); - nd = Py_SIZE(argdefs); - } - else { - d = NULL; - nd = 0; - } -#if PY_MAJOR_VERSION >= 3 - result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, kwdefs, closure); -#else - result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, closure); -#endif - Py_XDECREF(kwtuple); -done: - Py_LeaveRecursiveCall(); - return result; -} -#endif -#endif - -/* PyCFunctionFastCall */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { - PyCFunctionObject *func = (PyCFunctionObject*)func_obj; - PyCFunction meth = PyCFunction_GET_FUNCTION(func); - PyObject *self = PyCFunction_GET_SELF(func); - int flags = PyCFunction_GET_FLAGS(func); - assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); - assert(nargs >= 0); - assert(nargs == 0 || args != NULL); - /* _PyCFunction_FastCallDict() must not be called with an exception set, - because it may clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!PyErr_Occurred()); - if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); - } else { - return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); - } -} -#endif - -/* PyObjectCall */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *result; - ternaryfunc call = func->ob_type->tp_call; - if (unlikely(!call)) - return PyObject_Call(func, arg, kw); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* RaiseTooManyValuesToUnpack */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { - PyErr_Format(PyExc_ValueError, - "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); -} - -/* RaiseNeedMoreValuesToUnpack */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { - PyErr_Format(PyExc_ValueError, - "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", - index, (index == 1) ? "" : "s"); -} - -/* IterFinish */ -static CYTHON_INLINE int __Pyx_IterFinish(void) { -#if CYTHON_FAST_THREAD_STATE - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* exc_type = tstate->curexc_type; - if (unlikely(exc_type)) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) { - PyObject *exc_value, *exc_tb; - exc_value = tstate->curexc_value; - exc_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; - Py_DECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - return 0; - } else { - return -1; - } - } - return 0; -#else - if (unlikely(PyErr_Occurred())) { - if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) { - PyErr_Clear(); - return 0; - } else { - return -1; - } - } - return 0; -#endif -} - -/* UnpackItemEndCheck */ -static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { - if (unlikely(retval)) { - Py_DECREF(retval); - __Pyx_RaiseTooManyValuesError(expected); - return -1; - } else { - return __Pyx_IterFinish(); - } - return 0; -} - -/* PyObjectCall2Args */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { - PyObject *args, *result = NULL; - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyFunction_FastCall(function, args, 2); - } - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyCFunction_FastCall(function, args, 2); - } - #endif - args = PyTuple_New(2); - if (unlikely(!args)) goto done; - Py_INCREF(arg1); - PyTuple_SET_ITEM(args, 0, arg1); - Py_INCREF(arg2); - PyTuple_SET_ITEM(args, 1, arg2); - Py_INCREF(function); - result = __Pyx_PyObject_Call(function, args, NULL); - Py_DECREF(args); - Py_DECREF(function); -done: - return result; -} - -/* PyObjectCallMethO */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { - PyObject *self, *result; - PyCFunction cfunc; - cfunc = PyCFunction_GET_FUNCTION(func); - self = PyCFunction_GET_SELF(func); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = cfunc(self, arg); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallOneArg */ -#if CYTHON_COMPILING_IN_CPYTHON -static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_New(1); - if (unlikely(!args)) return NULL; - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 0, arg); - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, &arg, 1); - } -#endif - if (likely(PyCFunction_Check(func))) { - if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { - return __Pyx_PyObject_CallMethO(func, arg); -#if CYTHON_FAST_PYCCALL - } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { - return __Pyx_PyCFunction_FastCall(func, &arg, 1); -#endif - } - } - return __Pyx__PyObject_CallOneArg(func, arg); -} -#else -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_Pack(1, arg); - if (unlikely(!args)) return NULL; - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -#endif - -/* MemviewSliceInit */ -static int -__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview, - int ndim, - __Pyx_memviewslice *memviewslice, - int memview_is_new_reference) -{ - __Pyx_RefNannyDeclarations - int i, retval=-1; - Py_buffer *buf = &memview->view; - __Pyx_RefNannySetupContext("init_memviewslice", 0); - if (unlikely(memviewslice->memview || memviewslice->data)) { - PyErr_SetString(PyExc_ValueError, - "memviewslice is already initialized!"); - goto fail; - } - if (buf->strides) { - for (i = 0; i < ndim; i++) { - memviewslice->strides[i] = buf->strides[i]; - } - } else { - Py_ssize_t stride = buf->itemsize; - for (i = ndim - 1; i >= 0; i--) { - memviewslice->strides[i] = stride; - stride *= buf->shape[i]; - } - } - for (i = 0; i < ndim; i++) { - memviewslice->shape[i] = buf->shape[i]; - if (buf->suboffsets) { - memviewslice->suboffsets[i] = buf->suboffsets[i]; - } else { - memviewslice->suboffsets[i] = -1; - } - } - memviewslice->memview = memview; - memviewslice->data = (char *)buf->buf; - if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) { - Py_INCREF(memview); - } - retval = 0; - goto no_fail; -fail: - memviewslice->memview = 0; - memviewslice->data = 0; - retval = -1; -no_fail: - __Pyx_RefNannyFinishContext(); - return retval; -} -#ifndef Py_NO_RETURN -#define Py_NO_RETURN -#endif -static void __pyx_fatalerror(const char *fmt, ...) Py_NO_RETURN { - va_list vargs; - char msg[200]; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, fmt); -#else - va_start(vargs); -#endif - vsnprintf(msg, 200, fmt, vargs); - va_end(vargs); - Py_FatalError(msg); -} -static CYTHON_INLINE int -__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count, - PyThread_type_lock lock) -{ - int result; - PyThread_acquire_lock(lock, 1); - result = (*acquisition_count)++; - PyThread_release_lock(lock); - return result; -} -static CYTHON_INLINE int -__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count, - PyThread_type_lock lock) -{ - int result; - PyThread_acquire_lock(lock, 1); - result = (*acquisition_count)--; - PyThread_release_lock(lock); - return result; -} -static CYTHON_INLINE void -__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno) -{ - int first_time; - struct __pyx_memoryview_obj *memview = memslice->memview; - if (unlikely(!memview || (PyObject *) memview == Py_None)) - return; - if (unlikely(__pyx_get_slice_count(memview) < 0)) - __pyx_fatalerror("Acquisition count is %d (line %d)", - __pyx_get_slice_count(memview), lineno); - first_time = __pyx_add_acquisition_count(memview) == 0; - if (unlikely(first_time)) { - if (have_gil) { - Py_INCREF((PyObject *) memview); - } else { - PyGILState_STATE _gilstate = PyGILState_Ensure(); - Py_INCREF((PyObject *) memview); - PyGILState_Release(_gilstate); - } - } -} -static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice, - int have_gil, int lineno) { - int last_time; - struct __pyx_memoryview_obj *memview = memslice->memview; - if (unlikely(!memview || (PyObject *) memview == Py_None)) { - memslice->memview = NULL; - return; - } - if (unlikely(__pyx_get_slice_count(memview) <= 0)) - __pyx_fatalerror("Acquisition count is %d (line %d)", - __pyx_get_slice_count(memview), lineno); - last_time = __pyx_sub_acquisition_count(memview) == 1; - memslice->data = NULL; - if (unlikely(last_time)) { - if (have_gil) { - Py_CLEAR(memslice->memview); - } else { - PyGILState_STATE _gilstate = PyGILState_Ensure(); - Py_CLEAR(memslice->memview); - PyGILState_Release(_gilstate); - } - } else { - memslice->memview = NULL; - } -} - -/* PyIntBinop */ -#if !CYTHON_COMPILING_IN_PYPY -static PyObject* __Pyx_PyInt_SubtractObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, int inplace, int zerodivision_check) { - (void)inplace; - (void)zerodivision_check; - #if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(op1))) { - const long b = intval; - long x; - long a = PyInt_AS_LONG(op1); - x = (long)((unsigned long)a - b); - if (likely((x^a) >= 0 || (x^~b) >= 0)) - return PyInt_FromLong(x); - return PyLong_Type.tp_as_number->nb_subtract(op1, op2); - } - #endif - #if CYTHON_USE_PYLONG_INTERNALS - if (likely(PyLong_CheckExact(op1))) { - const long b = intval; - long a, x; -#ifdef HAVE_LONG_LONG - const PY_LONG_LONG llb = intval; - PY_LONG_LONG lla, llx; -#endif - const digit* digits = ((PyLongObject*)op1)->ob_digit; - const Py_ssize_t size = Py_SIZE(op1); - if (likely(__Pyx_sst_abs(size) <= 1)) { - a = likely(size) ? digits[0] : 0; - if (size == -1) a = -a; - } else { - switch (size) { - case -2: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { - lla = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case 2: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { - lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case -3: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { - lla = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case 3: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { - lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case -4: - if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { - lla = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case 4: - if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { - lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - default: return PyLong_Type.tp_as_number->nb_subtract(op1, op2); - } - } - x = a - b; - return PyLong_FromLong(x); -#ifdef HAVE_LONG_LONG - long_long: - llx = lla - llb; - return PyLong_FromLongLong(llx); -#endif - - - } - #endif - if (PyFloat_CheckExact(op1)) { - const long b = intval; - double a = PyFloat_AS_DOUBLE(op1); - double result; - PyFPE_START_PROTECT("subtract", return NULL) - result = ((double)a) - (double)b; - PyFPE_END_PROTECT(result) - return PyFloat_FromDouble(result); - } - return (inplace ? PyNumber_InPlaceSubtract : PyNumber_Subtract)(op1, op2); -} -#endif - -/* PyErrFetchRestore */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} -#endif - -/* RaiseException */ -#if PY_MAJOR_VERSION < 3 -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, - CYTHON_UNUSED PyObject *cause) { - __Pyx_PyThreadState_declare - Py_XINCREF(type); - if (!value || value == Py_None) - value = NULL; - else - Py_INCREF(value); - if (!tb || tb == Py_None) - tb = NULL; - else { - Py_INCREF(tb); - if (!PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } - } - if (PyType_Check(type)) { -#if CYTHON_COMPILING_IN_PYPY - if (!value) { - Py_INCREF(Py_None); - value = Py_None; - } -#endif - PyErr_NormalizeException(&type, &value, &tb); - } else { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - value = type; - type = (PyObject*) Py_TYPE(type); - Py_INCREF(type); - if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto raise_error; - } - } - __Pyx_PyThreadState_assign - __Pyx_ErrRestore(type, value, tb); - return; -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(tb); - return; -} -#else -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - PyObject* owned_instance = NULL; - if (tb == Py_None) { - tb = 0; - } else if (tb && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto bad; - } - if (value == Py_None) - value = 0; - if (PyExceptionInstance_Check(type)) { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto bad; - } - value = type; - type = (PyObject*) Py_TYPE(value); - } else if (PyExceptionClass_Check(type)) { - PyObject *instance_class = NULL; - if (value && PyExceptionInstance_Check(value)) { - instance_class = (PyObject*) Py_TYPE(value); - if (instance_class != type) { - int is_subclass = PyObject_IsSubclass(instance_class, type); - if (!is_subclass) { - instance_class = NULL; - } else if (unlikely(is_subclass == -1)) { - goto bad; - } else { - type = instance_class; - } - } - } - if (!instance_class) { - PyObject *args; - if (!value) - args = PyTuple_New(0); - else if (PyTuple_Check(value)) { - Py_INCREF(value); - args = value; - } else - args = PyTuple_Pack(1, value); - if (!args) - goto bad; - owned_instance = PyObject_Call(type, args, NULL); - Py_DECREF(args); - if (!owned_instance) - goto bad; - value = owned_instance; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto bad; - } - } - } else { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto bad; - } - if (cause) { - PyObject *fixed_cause; - if (cause == Py_None) { - fixed_cause = NULL; - } else if (PyExceptionClass_Check(cause)) { - fixed_cause = PyObject_CallObject(cause, NULL); - if (fixed_cause == NULL) - goto bad; - } else if (PyExceptionInstance_Check(cause)) { - fixed_cause = cause; - Py_INCREF(fixed_cause); - } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); - goto bad; - } - PyException_SetCause(value, fixed_cause); - } - PyErr_SetObject(type, value); - if (tb) { -#if CYTHON_COMPILING_IN_PYPY - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); - Py_INCREF(tb); - PyErr_Restore(tmp_type, tmp_value, tb); - Py_XDECREF(tmp_tb); -#else - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* tmp_tb = tstate->curexc_traceback; - if (tb != tmp_tb) { - Py_INCREF(tb); - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_tb); - } -#endif - } -bad: - Py_XDECREF(owned_instance); - return; -} -#endif - -/* DictGetItem */ -#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY -static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { - PyObject *value; - value = PyDict_GetItemWithError(d, key); - if (unlikely(!value)) { - if (!PyErr_Occurred()) { - if (unlikely(PyTuple_Check(key))) { - PyObject* args = PyTuple_Pack(1, key); - if (likely(args)) { - PyErr_SetObject(PyExc_KeyError, args); - Py_DECREF(args); - } - } else { - PyErr_SetObject(PyExc_KeyError, key); - } - } - return NULL; - } - Py_INCREF(value); - return value; -} -#endif - -/* RaiseNoneIterError */ -static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); -} - -/* ExtTypeTest */ -static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - if (likely(__Pyx_TypeCheck(obj, type))) - return 1; - PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", - Py_TYPE(obj)->tp_name, type->tp_name); - return 0; -} - -/* GetTopmostException */ -#if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * -__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) -{ - _PyErr_StackItem *exc_info = tstate->exc_info; - while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && - exc_info->previous_item != NULL) - { - exc_info = exc_info->previous_item; - } - return exc_info; -} -#endif - -/* SaveResetException */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); - *type = exc_info->exc_type; - *value = exc_info->exc_value; - *tb = exc_info->exc_traceback; - #else - *type = tstate->exc_type; - *value = tstate->exc_value; - *tb = tstate->exc_traceback; - #endif - Py_XINCREF(*type); - Py_XINCREF(*value); - Py_XINCREF(*tb); -} -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = type; - exc_info->exc_value = value; - exc_info->exc_traceback = tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = type; - tstate->exc_value = value; - tstate->exc_traceback = tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -#endif - -/* PyErrExceptionMatches */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; icurexc_type; - if (exc_type == err) return 1; - if (unlikely(!exc_type)) return 0; - if (unlikely(PyTuple_Check(err))) - return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); - return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); -} -#endif - -/* GetException */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) -#endif -{ - PyObject *local_type, *local_value, *local_tb; -#if CYTHON_FAST_THREAD_STATE - PyObject *tmp_type, *tmp_value, *tmp_tb; - local_type = tstate->curexc_type; - local_value = tstate->curexc_value; - local_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -#else - PyErr_Fetch(&local_type, &local_value, &local_tb); -#endif - PyErr_NormalizeException(&local_type, &local_value, &local_tb); -#if CYTHON_FAST_THREAD_STATE - if (unlikely(tstate->curexc_type)) -#else - if (unlikely(PyErr_Occurred())) -#endif - goto bad; - #if PY_MAJOR_VERSION >= 3 - if (local_tb) { - if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) - goto bad; - } - #endif - Py_XINCREF(local_tb); - Py_XINCREF(local_type); - Py_XINCREF(local_value); - *type = local_type; - *value = local_value; - *tb = local_tb; -#if CYTHON_FAST_THREAD_STATE - #if CYTHON_USE_EXC_INFO_STACK - { - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = local_type; - exc_info->exc_value = local_value; - exc_info->exc_traceback = local_tb; - } - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = local_type; - tstate->exc_value = local_value; - tstate->exc_traceback = local_tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#else - PyErr_SetExcInfo(local_type, local_value, local_tb); -#endif - return 0; -bad: - *type = 0; - *value = 0; - *tb = 0; - Py_XDECREF(local_type); - Py_XDECREF(local_value); - Py_XDECREF(local_tb); - return -1; -} - -/* ArgTypeTest */ -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) -{ - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - else if (exact) { - #if PY_MAJOR_VERSION == 2 - if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; - #endif - } - else { - if (likely(__Pyx_TypeCheck(obj, type))) return 1; - } - PyErr_Format(PyExc_TypeError, - "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", - name, type->tp_name, Py_TYPE(obj)->tp_name); - return 0; -} - -/* BytesEquals */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY - return PyObject_RichCompareBool(s1, s2, equals); -#else - if (s1 == s2) { - return (equals == Py_EQ); - } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { - const char *ps1, *ps2; - Py_ssize_t length = PyBytes_GET_SIZE(s1); - if (length != PyBytes_GET_SIZE(s2)) - return (equals == Py_NE); - ps1 = PyBytes_AS_STRING(s1); - ps2 = PyBytes_AS_STRING(s2); - if (ps1[0] != ps2[0]) { - return (equals == Py_NE); - } else if (length == 1) { - return (equals == Py_EQ); - } else { - int result; -#if CYTHON_USE_UNICODE_INTERNALS - Py_hash_t hash1, hash2; - hash1 = ((PyBytesObject*)s1)->ob_shash; - hash2 = ((PyBytesObject*)s2)->ob_shash; - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - return (equals == Py_NE); - } -#endif - result = memcmp(ps1, ps2, (size_t)length); - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { - return (equals == Py_NE); - } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { - return (equals == Py_NE); - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -#endif -} - -/* UnicodeEquals */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY - return PyObject_RichCompareBool(s1, s2, equals); -#else -#if PY_MAJOR_VERSION < 3 - PyObject* owned_ref = NULL; -#endif - int s1_is_unicode, s2_is_unicode; - if (s1 == s2) { - goto return_eq; - } - s1_is_unicode = PyUnicode_CheckExact(s1); - s2_is_unicode = PyUnicode_CheckExact(s2); -#if PY_MAJOR_VERSION < 3 - if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { - owned_ref = PyUnicode_FromObject(s2); - if (unlikely(!owned_ref)) - return -1; - s2 = owned_ref; - s2_is_unicode = 1; - } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { - owned_ref = PyUnicode_FromObject(s1); - if (unlikely(!owned_ref)) - return -1; - s1 = owned_ref; - s1_is_unicode = 1; - } else if (((!s2_is_unicode) & (!s1_is_unicode))) { - return __Pyx_PyBytes_Equals(s1, s2, equals); - } -#endif - if (s1_is_unicode & s2_is_unicode) { - Py_ssize_t length; - int kind; - void *data1, *data2; - if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) - return -1; - length = __Pyx_PyUnicode_GET_LENGTH(s1); - if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { - goto return_ne; - } -#if CYTHON_USE_UNICODE_INTERNALS - { - Py_hash_t hash1, hash2; - #if CYTHON_PEP393_ENABLED - hash1 = ((PyASCIIObject*)s1)->hash; - hash2 = ((PyASCIIObject*)s2)->hash; - #else - hash1 = ((PyUnicodeObject*)s1)->hash; - hash2 = ((PyUnicodeObject*)s2)->hash; - #endif - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - goto return_ne; - } - } -#endif - kind = __Pyx_PyUnicode_KIND(s1); - if (kind != __Pyx_PyUnicode_KIND(s2)) { - goto return_ne; - } - data1 = __Pyx_PyUnicode_DATA(s1); - data2 = __Pyx_PyUnicode_DATA(s2); - if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { - goto return_ne; - } else if (length == 1) { - goto return_eq; - } else { - int result = memcmp(data1, data2, (size_t)(length * kind)); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & s2_is_unicode) { - goto return_ne; - } else if ((s2 == Py_None) & s1_is_unicode) { - goto return_ne; - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -return_eq: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ); -return_ne: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_NE); -#endif -} - -/* None */ -static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) { - Py_ssize_t q = a / b; - Py_ssize_t r = a - q*b; - q -= ((r != 0) & ((r ^ b) < 0)); - return q; -} - -/* GetAttr */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { -#if CYTHON_USE_TYPE_SLOTS -#if PY_MAJOR_VERSION >= 3 - if (likely(PyUnicode_Check(n))) -#else - if (likely(PyString_Check(n))) -#endif - return __Pyx_PyObject_GetAttrStr(o, n); -#endif - return PyObject_GetAttr(o, n); -} - -/* GetItemInt */ -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { - PyObject *r; - if (!j) return NULL; - r = PyObject_GetItem(o, j); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyList_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { - PyObject *r = PyList_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyTuple_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { - PyObject *r = PyList_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } - else if (PyTuple_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } else { - PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (likely(m && m->sq_item)) { - if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { - Py_ssize_t l = m->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - } - } - return m->sq_item(o, i); - } - } -#else - if (is_list || PySequence_Check(o)) { - return PySequence_GetItem(o, i); - } -#endif - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -} - -/* ObjectGetItem */ -#if CYTHON_USE_TYPE_SLOTS -static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject* index) { - PyObject *runerr; - Py_ssize_t key_value; - PySequenceMethods *m = Py_TYPE(obj)->tp_as_sequence; - if (unlikely(!(m && m->sq_item))) { - PyErr_Format(PyExc_TypeError, "'%.200s' object is not subscriptable", Py_TYPE(obj)->tp_name); - return NULL; - } - key_value = __Pyx_PyIndex_AsSsize_t(index); - if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { - return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); - } - if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { - PyErr_Clear(); - PyErr_Format(PyExc_IndexError, "cannot fit '%.200s' into an index-sized integer", Py_TYPE(index)->tp_name); - } - return NULL; -} -static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key) { - PyMappingMethods *m = Py_TYPE(obj)->tp_as_mapping; - if (likely(m && m->mp_subscript)) { - return m->mp_subscript(obj, key); - } - return __Pyx_PyObject_GetIndex(obj, key); -} -#endif - -/* decode_c_string */ -static CYTHON_INLINE PyObject* __Pyx_decode_c_string( - const char* cstring, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { - Py_ssize_t length; - if (unlikely((start < 0) | (stop < 0))) { - size_t slen = strlen(cstring); - if (unlikely(slen > (size_t) PY_SSIZE_T_MAX)) { - PyErr_SetString(PyExc_OverflowError, - "c-string too long to convert to Python"); - return NULL; - } - length = (Py_ssize_t) slen; - if (start < 0) { - start += length; - if (start < 0) - start = 0; - } - if (stop < 0) - stop += length; - } - if (unlikely(stop <= start)) - return __Pyx_NewRef(__pyx_empty_unicode); - length = stop - start; - cstring += start; - if (decode_func) { - return decode_func(cstring, length, errors); - } else { - return PyUnicode_Decode(cstring, length, encoding, errors); - } -} - -/* GetAttr3 */ -static PyObject *__Pyx_GetAttr3Default(PyObject *d) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - return NULL; - __Pyx_PyErr_Clear(); - Py_INCREF(d); - return d; -} -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { - PyObject *r = __Pyx_GetAttr(o, n); - return (likely(r)) ? r : __Pyx_GetAttr3Default(d); -} - -/* SwapException */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = *type; - exc_info->exc_value = *value; - exc_info->exc_traceback = *tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = *type; - tstate->exc_value = *value; - tstate->exc_traceback = *tb; - #endif - *type = tmp_type; - *value = tmp_value; - *tb = tmp_tb; -} -#else -static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); - PyErr_SetExcInfo(*type, *value, *tb); - *type = tmp_type; - *value = tmp_value; - *tb = tmp_tb; -} -#endif - -/* Import */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { - PyObject *empty_list = 0; - PyObject *module = 0; - PyObject *global_dict = 0; - PyObject *empty_dict = 0; - PyObject *list; - #if PY_MAJOR_VERSION < 3 - PyObject *py_import; - py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); - if (!py_import) - goto bad; - #endif - if (from_list) - list = from_list; - else { - empty_list = PyList_New(0); - if (!empty_list) - goto bad; - list = empty_list; - } - global_dict = PyModule_GetDict(__pyx_m); - if (!global_dict) - goto bad; - empty_dict = PyDict_New(); - if (!empty_dict) - goto bad; - { - #if PY_MAJOR_VERSION >= 3 - if (level == -1) { - if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, 1); - if (!module) { - if (!PyErr_ExceptionMatches(PyExc_ImportError)) - goto bad; - PyErr_Clear(); - } - } - level = 0; - } - #endif - if (!module) { - #if PY_MAJOR_VERSION < 3 - PyObject *py_level = PyInt_FromLong(level); - if (!py_level) - goto bad; - module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); - Py_DECREF(py_level); - #else - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, level); - #endif - } - } -bad: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_import); - #endif - Py_XDECREF(empty_list); - Py_XDECREF(empty_dict); - return module; -} - -/* FastTypeChecks */ -#if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = a->tp_base; - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); -} -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - } - __Pyx_ErrRestore(exception, value, tb); - return res; -} -#else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; - if (!res) { - res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); - } - return res; -} -#endif -static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - assert(PyExceptionClass_Check(exc_type)); - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; i= 0 || (x^b) >= 0)) - return PyInt_FromLong(x); - return PyLong_Type.tp_as_number->nb_add(op1, op2); - } - #endif - #if CYTHON_USE_PYLONG_INTERNALS - if (likely(PyLong_CheckExact(op1))) { - const long b = intval; - long a, x; -#ifdef HAVE_LONG_LONG - const PY_LONG_LONG llb = intval; - PY_LONG_LONG lla, llx; -#endif - const digit* digits = ((PyLongObject*)op1)->ob_digit; - const Py_ssize_t size = Py_SIZE(op1); - if (likely(__Pyx_sst_abs(size) <= 1)) { - a = likely(size) ? digits[0] : 0; - if (size == -1) a = -a; - } else { - switch (size) { - case -2: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { - lla = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case 2: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { - lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case -3: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { - lla = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case 3: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { - lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case -4: - if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { - lla = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - case 4: - if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); - break; -#ifdef HAVE_LONG_LONG - } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { - lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); - goto long_long; -#endif - } - CYTHON_FALLTHROUGH; - default: return PyLong_Type.tp_as_number->nb_add(op1, op2); - } - } - x = a + b; - return PyLong_FromLong(x); -#ifdef HAVE_LONG_LONG - long_long: - llx = lla + llb; - return PyLong_FromLongLong(llx); -#endif - - - } - #endif - if (PyFloat_CheckExact(op1)) { - const long b = intval; - double a = PyFloat_AS_DOUBLE(op1); - double result; - PyFPE_START_PROTECT("add", return NULL) - result = ((double)a) + (double)b; - PyFPE_END_PROTECT(result) - return PyFloat_FromDouble(result); - } - return (inplace ? PyNumber_InPlaceAdd : PyNumber_Add)(op1, op2); -} -#endif - -/* None */ -static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) { - PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname); -} - -/* None */ -static CYTHON_INLINE long __Pyx_div_long(long a, long b) { - long q = a / b; - long r = a - q*b; - q -= ((r != 0) & ((r ^ b) < 0)); - return q; -} - -/* ImportFrom */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { - PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); - if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_ImportError, - #if PY_MAJOR_VERSION < 3 - "cannot import name %.230s", PyString_AS_STRING(name)); - #else - "cannot import name %S", name); - #endif - } - return value; -} - -/* HasAttr */ -static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { - PyObject *r; - if (unlikely(!__Pyx_PyBaseString_Check(n))) { - PyErr_SetString(PyExc_TypeError, - "hasattr(): attribute name must be string"); - return -1; - } - r = __Pyx_GetAttr(o, n); - if (unlikely(!r)) { - PyErr_Clear(); - return 0; - } else { - Py_DECREF(r); - return 1; - } -} - -/* StringJoin */ -#if !CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values) { - return PyObject_CallMethodObjArgs(sep, __pyx_n_s_join, values, NULL); -} -#endif - -/* PyObject_GenericGetAttrNoDict */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'%.50s' object has no attribute '%U'", - tp->tp_name, attr_name); -#else - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, PyString_AS_STRING(attr_name)); -#endif - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { - PyObject *descr; - PyTypeObject *tp = Py_TYPE(obj); - if (unlikely(!PyString_Check(attr_name))) { - return PyObject_GenericGetAttr(obj, attr_name); - } - assert(!tp->tp_dictoffset); - descr = _PyType_Lookup(tp, attr_name); - if (unlikely(!descr)) { - return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); - } - Py_INCREF(descr); - #if PY_MAJOR_VERSION < 3 - if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) - #endif - { - descrgetfunc f = Py_TYPE(descr)->tp_descr_get; - if (unlikely(f)) { - PyObject *res = f(descr, obj, (PyObject *)tp); - Py_DECREF(descr); - return res; - } - } - return descr; -} -#endif - -/* PyObject_GenericGetAttr */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { - if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { - return PyObject_GenericGetAttr(obj, attr_name); - } - return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); -} -#endif - -/* SetVTable */ -static int __Pyx_SetVtable(PyObject *dict, void *vtable) { -#if PY_VERSION_HEX >= 0x02070000 - PyObject *ob = PyCapsule_New(vtable, 0, 0); -#else - PyObject *ob = PyCObject_FromVoidPtr(vtable, 0); -#endif - if (!ob) - goto bad; - if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0) - goto bad; - Py_DECREF(ob); - return 0; -bad: - Py_XDECREF(ob); - return -1; -} - -/* PyObjectGetAttrStrNoError */ -static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - __Pyx_PyErr_Clear(); -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { - PyObject *result; -#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { - return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); - } -#endif - result = __Pyx_PyObject_GetAttrStr(obj, attr_name); - if (unlikely(!result)) { - __Pyx_PyObject_GetAttrStr_ClearAttributeError(); - } - return result; -} - -/* SetupReduce */ -static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { - int ret; - PyObject *name_attr; - name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name_2); - if (likely(name_attr)) { - ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); - } else { - ret = -1; - } - if (unlikely(ret < 0)) { - PyErr_Clear(); - ret = 0; - } - Py_XDECREF(name_attr); - return ret; -} -static int __Pyx_setup_reduce(PyObject* type_obj) { - int ret = 0; - PyObject *object_reduce = NULL; - PyObject *object_reduce_ex = NULL; - PyObject *reduce = NULL; - PyObject *reduce_ex = NULL; - PyObject *reduce_cython = NULL; - PyObject *setstate = NULL; - PyObject *setstate_cython = NULL; -#if CYTHON_USE_PYTYPE_LOOKUP - if (_PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; -#else - if (PyObject_HasAttr(type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; -#endif -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#else - object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#endif - reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; - if (reduce_ex == object_reduce_ex) { -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#else - object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#endif - reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; - if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { - reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); - if (likely(reduce_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (reduce == object_reduce || PyErr_Occurred()) { - goto __PYX_BAD; - } - setstate = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate); - if (!setstate) PyErr_Clear(); - if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { - setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); - if (likely(setstate_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (!setstate || PyErr_Occurred()) { - goto __PYX_BAD; - } - } - PyType_Modified((PyTypeObject*)type_obj); - } - } - goto __PYX_GOOD; -__PYX_BAD: - if (!PyErr_Occurred()) - PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name); - ret = -1; -__PYX_GOOD: -#if !CYTHON_USE_PYTYPE_LOOKUP - Py_XDECREF(object_reduce); - Py_XDECREF(object_reduce_ex); -#endif - Py_XDECREF(reduce); - Py_XDECREF(reduce_ex); - Py_XDECREF(reduce_cython); - Py_XDECREF(setstate); - Py_XDECREF(setstate_cython); - return ret; -} - -/* TypeImport */ -#ifndef __PYX_HAVE_RT_ImportType -#define __PYX_HAVE_RT_ImportType -static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, - size_t size, enum __Pyx_ImportType_CheckSize check_size) -{ - PyObject *result = 0; - char warning[200]; - Py_ssize_t basicsize; -#ifdef Py_LIMITED_API - PyObject *py_basicsize; -#endif - result = PyObject_GetAttrString(module, class_name); - if (!result) - goto bad; - if (!PyType_Check(result)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%.200s is not a type object", - module_name, class_name); - goto bad; - } -#ifndef Py_LIMITED_API - basicsize = ((PyTypeObject *)result)->tp_basicsize; -#else - py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); - if (!py_basicsize) - goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; -#endif - if ((size_t)basicsize < size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { - PyOS_snprintf(warning, sizeof(warning), - "%s.%s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; - } - return (PyTypeObject *)result; -bad: - Py_XDECREF(result); - return NULL; -} -#endif - -/* CLineInTraceback */ -#ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { - PyObject *use_cline; - PyObject *ptype, *pvalue, *ptraceback; -#if CYTHON_COMPILING_IN_CPYTHON - PyObject **cython_runtime_dict; -#endif - if (unlikely(!__pyx_cython_runtime)) { - return c_line; - } - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); -#if CYTHON_COMPILING_IN_CPYTHON - cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); - if (likely(cython_runtime_dict)) { - __PYX_PY_DICT_LOOKUP_IF_MODIFIED( - use_cline, *cython_runtime_dict, - __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) - } else -#endif - { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); - if (use_cline_obj) { - use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; - Py_DECREF(use_cline_obj); - } else { - PyErr_Clear(); - use_cline = NULL; - } - } - if (!use_cline) { - c_line = 0; - PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); - } - else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { - c_line = 0; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - return c_line; -} -#endif - -/* CodeObjectCache */ -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { - int start = 0, mid = 0, end = count - 1; - if (end >= 0 && code_line > entries[end].code_line) { - return count; - } - while (start < end) { - mid = start + (end - start) / 2; - if (code_line < entries[mid].code_line) { - end = mid; - } else if (code_line > entries[mid].code_line) { - start = mid + 1; - } else { - return mid; - } - } - if (code_line <= entries[mid].code_line) { - return mid; - } else { - return mid + 1; - } -} -static PyCodeObject *__pyx_find_code_object(int code_line) { - PyCodeObject* code_object; - int pos; - if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { - return NULL; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { - return NULL; - } - code_object = __pyx_code_cache.entries[pos].code_object; - Py_INCREF(code_object); - return code_object; -} -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { - int pos, i; - __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; - if (unlikely(!code_line)) { - return; - } - if (unlikely(!entries)) { - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); - if (likely(entries)) { - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = 64; - __pyx_code_cache.count = 1; - entries[0].code_line = code_line; - entries[0].code_object = code_object; - Py_INCREF(code_object); - } - return; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { - PyCodeObject* tmp = entries[pos].code_object; - entries[pos].code_object = code_object; - Py_DECREF(tmp); - return; - } - if (__pyx_code_cache.count == __pyx_code_cache.max_count) { - int new_max = __pyx_code_cache.max_count + 64; - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( - __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); - if (unlikely(!entries)) { - return; - } - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = new_max; - } - for (i=__pyx_code_cache.count; i>pos; i--) { - entries[i] = entries[i-1]; - } - entries[pos].code_line = code_line; - entries[pos].code_object = code_object; - __pyx_code_cache.count++; - Py_INCREF(code_object); -} - -/* AddTraceback */ -#include "compile.h" -#include "frameobject.h" -#include "traceback.h" -static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( - const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyObject *py_srcfile = 0; - PyObject *py_funcname = 0; - #if PY_MAJOR_VERSION < 3 - py_srcfile = PyString_FromString(filename); - #else - py_srcfile = PyUnicode_FromString(filename); - #endif - if (!py_srcfile) goto bad; - if (c_line) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - #else - py_funcname = PyUnicode_FromString(funcname); - #endif - } - if (!py_funcname) goto bad; - py_code = __Pyx_PyCode_New( - 0, - 0, - 0, - 0, - 0, - __pyx_empty_bytes, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - py_line, - __pyx_empty_bytes /*PyObject *lnotab*/ - ); - Py_DECREF(py_srcfile); - Py_DECREF(py_funcname); - return py_code; -bad: - Py_XDECREF(py_srcfile); - Py_XDECREF(py_funcname); - return NULL; -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - if (c_line) { - c_line = __Pyx_CLineForTraceback(tstate, c_line); - } - py_code = __pyx_find_code_object(c_line ? -c_line : py_line); - if (!py_code) { - py_code = __Pyx_CreateCodeObjectForTraceback( - funcname, c_line, py_line, filename); - if (!py_code) goto bad; - __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); - } - py_frame = PyFrame_New( - tstate, /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - __pyx_d, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - __Pyx_PyFrame_SetLineNumber(py_frame, py_line); - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - -#if PY_MAJOR_VERSION < 3 -static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { - if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); - if (__Pyx_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags); - if (__Pyx_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags); - PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name); - return -1; -} -static void __Pyx_ReleaseBuffer(Py_buffer *view) { - PyObject *obj = view->obj; - if (!obj) return; - if (PyObject_CheckBuffer(obj)) { - PyBuffer_Release(view); - return; - } - if ((0)) {} - view->obj = NULL; - Py_DECREF(obj); -} -#endif - - -/* MemviewSliceIsContig */ -static int -__pyx_memviewslice_is_contig(const __Pyx_memviewslice mvs, char order, int ndim) -{ - int i, index, step, start; - Py_ssize_t itemsize = mvs.memview->view.itemsize; - if (order == 'F') { - step = 1; - start = 0; - } else { - step = -1; - start = ndim - 1; - } - for (i = 0; i < ndim; i++) { - index = start + step * i; - if (mvs.suboffsets[index] >= 0 || mvs.strides[index] != itemsize) - return 0; - itemsize *= mvs.shape[index]; - } - return 1; -} - -/* OverlappingSlices */ -static void -__pyx_get_array_memory_extents(__Pyx_memviewslice *slice, - void **out_start, void **out_end, - int ndim, size_t itemsize) -{ - char *start, *end; - int i; - start = end = slice->data; - for (i = 0; i < ndim; i++) { - Py_ssize_t stride = slice->strides[i]; - Py_ssize_t extent = slice->shape[i]; - if (extent == 0) { - *out_start = *out_end = start; - return; - } else { - if (stride > 0) - end += stride * (extent - 1); - else - start += stride * (extent - 1); - } - } - *out_start = start; - *out_end = end + itemsize; -} -static int -__pyx_slices_overlap(__Pyx_memviewslice *slice1, - __Pyx_memviewslice *slice2, - int ndim, size_t itemsize) -{ - void *start1, *end1, *start2, *end2; - __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize); - __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize); - return (start1 < end2) && (start2 < end1); -} - -/* Capsule */ -static CYTHON_INLINE PyObject * -__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig) -{ - PyObject *cobj; -#if PY_VERSION_HEX >= 0x02070000 - cobj = PyCapsule_New(p, sig, NULL); -#else - cobj = PyCObject_FromVoidPtr(p, NULL); -#endif - return cobj; -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { - const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(int) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(int) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(int) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(int), - little, !is_unsigned); - } -} - -/* CIntFromPyVerify */ -#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ - } - -/* Declarations */ -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { - return ::std::complex< float >(x, y); - } - #else - static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { - return x + y*(__pyx_t_float_complex)_Complex_I; - } - #endif -#else - static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { - __pyx_t_float_complex z; - z.real = x; - z.imag = y; - return z; - } -#endif - -/* Arithmetic */ -#if CYTHON_CCOMPLEX -#else - static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - return (a.real == b.real) && (a.imag == b.imag); - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - z.real = a.real + b.real; - z.imag = a.imag + b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - z.real = a.real - b.real; - z.imag = a.imag - b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - z.real = a.real * b.real - a.imag * b.imag; - z.imag = a.real * b.imag + a.imag * b.real; - return z; - } - #if 1 - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - if (b.imag == 0) { - return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); - } else if (fabsf(b.real) >= fabsf(b.imag)) { - if (b.real == 0 && b.imag == 0) { - return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.imag); - } else { - float r = b.imag / b.real; - float s = (float)(1.0) / (b.real + b.imag * r); - return __pyx_t_float_complex_from_parts( - (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); - } - } else { - float r = b.real / b.imag; - float s = (float)(1.0) / (b.imag + b.real * r); - return __pyx_t_float_complex_from_parts( - (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); - } - } - #else - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - if (b.imag == 0) { - return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); - } else { - float denom = b.real * b.real + b.imag * b.imag; - return __pyx_t_float_complex_from_parts( - (a.real * b.real + a.imag * b.imag) / denom, - (a.imag * b.real - a.real * b.imag) / denom); - } - } - #endif - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex a) { - __pyx_t_float_complex z; - z.real = -a.real; - z.imag = -a.imag; - return z; - } - static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex a) { - return (a.real == 0) && (a.imag == 0); - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex a) { - __pyx_t_float_complex z; - z.real = a.real; - z.imag = -a.imag; - return z; - } - #if 1 - static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex z) { - #if !defined(HAVE_HYPOT) || defined(_MSC_VER) - return sqrtf(z.real*z.real + z.imag*z.imag); - #else - return hypotf(z.real, z.imag); - #endif - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - float r, lnr, theta, z_r, z_theta; - if (b.imag == 0 && b.real == (int)b.real) { - if (b.real < 0) { - float denom = a.real * a.real + a.imag * a.imag; - a.real = a.real / denom; - a.imag = -a.imag / denom; - b.real = -b.real; - } - switch ((int)b.real) { - case 0: - z.real = 1; - z.imag = 0; - return z; - case 1: - return a; - case 2: - return __Pyx_c_prod_float(a, a); - case 3: - z = __Pyx_c_prod_float(a, a); - return __Pyx_c_prod_float(z, a); - case 4: - z = __Pyx_c_prod_float(a, a); - return __Pyx_c_prod_float(z, z); - } - } - if (a.imag == 0) { - if (a.real == 0) { - return a; - } else if (b.imag == 0) { - z.real = powf(a.real, b.real); - z.imag = 0; - return z; - } else if (a.real > 0) { - r = a.real; - theta = 0; - } else { - r = -a.real; - theta = atan2f(0.0, -1.0); - } - } else { - r = __Pyx_c_abs_float(a); - theta = atan2f(a.imag, a.real); - } - lnr = logf(r); - z_r = expf(lnr * b.real - theta * b.imag); - z_theta = theta * b.real + lnr * b.imag; - z.real = z_r * cosf(z_theta); - z.imag = z_r * sinf(z_theta); - return z; - } - #endif -#endif - -/* Declarations */ -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { - return ::std::complex< double >(x, y); - } - #else - static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { - return x + y*(__pyx_t_double_complex)_Complex_I; - } - #endif -#else - static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { - __pyx_t_double_complex z; - z.real = x; - z.imag = y; - return z; - } -#endif - -/* Arithmetic */ -#if CYTHON_CCOMPLEX -#else - static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - return (a.real == b.real) && (a.imag == b.imag); - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - z.real = a.real + b.real; - z.imag = a.imag + b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - z.real = a.real - b.real; - z.imag = a.imag - b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - z.real = a.real * b.real - a.imag * b.imag; - z.imag = a.real * b.imag + a.imag * b.real; - return z; - } - #if 1 - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - if (b.imag == 0) { - return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); - } else if (fabs(b.real) >= fabs(b.imag)) { - if (b.real == 0 && b.imag == 0) { - return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.imag); - } else { - double r = b.imag / b.real; - double s = (double)(1.0) / (b.real + b.imag * r); - return __pyx_t_double_complex_from_parts( - (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); - } - } else { - double r = b.real / b.imag; - double s = (double)(1.0) / (b.imag + b.real * r); - return __pyx_t_double_complex_from_parts( - (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); - } - } - #else - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - if (b.imag == 0) { - return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); - } else { - double denom = b.real * b.real + b.imag * b.imag; - return __pyx_t_double_complex_from_parts( - (a.real * b.real + a.imag * b.imag) / denom, - (a.imag * b.real - a.real * b.imag) / denom); - } - } - #endif - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex a) { - __pyx_t_double_complex z; - z.real = -a.real; - z.imag = -a.imag; - return z; - } - static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex a) { - return (a.real == 0) && (a.imag == 0); - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex a) { - __pyx_t_double_complex z; - z.real = a.real; - z.imag = -a.imag; - return z; - } - #if 1 - static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex z) { - #if !defined(HAVE_HYPOT) || defined(_MSC_VER) - return sqrt(z.real*z.real + z.imag*z.imag); - #else - return hypot(z.real, z.imag); - #endif - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - double r, lnr, theta, z_r, z_theta; - if (b.imag == 0 && b.real == (int)b.real) { - if (b.real < 0) { - double denom = a.real * a.real + a.imag * a.imag; - a.real = a.real / denom; - a.imag = -a.imag / denom; - b.real = -b.real; - } - switch ((int)b.real) { - case 0: - z.real = 1; - z.imag = 0; - return z; - case 1: - return a; - case 2: - return __Pyx_c_prod_double(a, a); - case 3: - z = __Pyx_c_prod_double(a, a); - return __Pyx_c_prod_double(z, a); - case 4: - z = __Pyx_c_prod_double(a, a); - return __Pyx_c_prod_double(z, z); - } - } - if (a.imag == 0) { - if (a.real == 0) { - return a; - } else if (b.imag == 0) { - z.real = pow(a.real, b.real); - z.imag = 0; - return z; - } else if (a.real > 0) { - r = a.real; - theta = 0; - } else { - r = -a.real; - theta = atan2(0.0, -1.0); - } - } else { - r = __Pyx_c_abs_double(a); - theta = atan2(a.imag, a.real); - } - lnr = log(r); - z_r = exp(lnr * b.real - theta * b.imag); - z_theta = theta * b.real + lnr * b.imag; - z.real = z_r * cos(z_theta); - z.imag = z_r * sin(z_theta); - return z; - } - #endif -#endif - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value) { - const enum NPY_TYPES neg_one = (enum NPY_TYPES) ((enum NPY_TYPES) 0 - (enum NPY_TYPES) 1), const_zero = (enum NPY_TYPES) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(enum NPY_TYPES) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(enum NPY_TYPES) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(enum NPY_TYPES) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(enum NPY_TYPES), - little, !is_unsigned); - } -} - -/* MemviewSliceCopyTemplate */ -static __Pyx_memviewslice -__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, - const char *mode, int ndim, - size_t sizeof_dtype, int contig_flag, - int dtype_is_object) -{ - __Pyx_RefNannyDeclarations - int i; - __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } }; - struct __pyx_memoryview_obj *from_memview = from_mvs->memview; - Py_buffer *buf = &from_memview->view; - PyObject *shape_tuple = NULL; - PyObject *temp_int = NULL; - struct __pyx_array_obj *array_obj = NULL; - struct __pyx_memoryview_obj *memview_obj = NULL; - __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0); - for (i = 0; i < ndim; i++) { - if (unlikely(from_mvs->suboffsets[i] >= 0)) { - PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with " - "indirect dimensions (axis %d)", i); - goto fail; - } - } - shape_tuple = PyTuple_New(ndim); - if (unlikely(!shape_tuple)) { - goto fail; - } - __Pyx_GOTREF(shape_tuple); - for(i = 0; i < ndim; i++) { - temp_int = PyInt_FromSsize_t(from_mvs->shape[i]); - if(unlikely(!temp_int)) { - goto fail; - } else { - PyTuple_SET_ITEM(shape_tuple, i, temp_int); - temp_int = NULL; - } - } - array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL); - if (unlikely(!array_obj)) { - goto fail; - } - __Pyx_GOTREF(array_obj); - memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new( - (PyObject *) array_obj, contig_flag, - dtype_is_object, - from_mvs->memview->typeinfo); - if (unlikely(!memview_obj)) - goto fail; - if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0)) - goto fail; - if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim, - dtype_is_object) < 0)) - goto fail; - goto no_fail; -fail: - __Pyx_XDECREF(new_mvs.memview); - new_mvs.memview = NULL; - new_mvs.data = NULL; -no_fail: - __Pyx_XDECREF(shape_tuple); - __Pyx_XDECREF(temp_int); - __Pyx_XDECREF(array_obj); - __Pyx_RefNannyFinishContext(); - return new_mvs; -} - -/* TypeInfoToFormat */ -static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type) { - struct __pyx_typeinfo_string result = { {0} }; - char *buf = (char *) result.string; - size_t size = type->size; - switch (type->typegroup) { - case 'H': - *buf = 'c'; - break; - case 'I': - case 'U': - if (size == 1) - *buf = (type->is_unsigned) ? 'B' : 'b'; - else if (size == 2) - *buf = (type->is_unsigned) ? 'H' : 'h'; - else if (size == 4) - *buf = (type->is_unsigned) ? 'I' : 'i'; - else if (size == 8) - *buf = (type->is_unsigned) ? 'Q' : 'q'; - break; - case 'P': - *buf = 'P'; - break; - case 'C': - { - __Pyx_TypeInfo complex_type = *type; - complex_type.typegroup = 'R'; - complex_type.size /= 2; - *buf++ = 'Z'; - *buf = __Pyx_TypeInfoToFormat(&complex_type).string[0]; - break; - } - case 'R': - if (size == 4) - *buf = 'f'; - else if (size == 8) - *buf = 'd'; - else - *buf = 'g'; - break; - } - return result; -} - -/* CIntFromPy */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(int) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(int) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) - case -2: - if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - } -#endif - if (sizeof(int) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - int val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (int) -1; - } - } else { - int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int) -1; - val = __Pyx_PyInt_As_int(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int"); - return (int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int"); - return (int) -1; -} - -/* CIntFromPy */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(long) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (long) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(long) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) - case -2: - if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - } -#endif - if (sizeof(long) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - long val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (long) -1; - } - } else { - long val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (long) -1; - val = __Pyx_PyInt_As_long(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to long"); - return (long) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to long"); - return (long) -1; -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(long) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(long) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(long) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(long), - little, !is_unsigned); - } -} - -/* CIntFromPy */ -static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) { - const char neg_one = (char) ((char) 0 - (char) 1), const_zero = (char) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(char) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (char) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (char) 0; - case 1: __PYX_VERIFY_RETURN_INT(char, digit, digits[0]) - case 2: - if (8 * sizeof(char) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) >= 2 * PyLong_SHIFT) { - return (char) (((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(char) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) >= 3 * PyLong_SHIFT) { - return (char) (((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(char) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) >= 4 * PyLong_SHIFT) { - return (char) (((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (char) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(char) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(char, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(char) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(char, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (char) 0; - case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(char, digit, +digits[0]) - case -2: - if (8 * sizeof(char) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) - 1 > 2 * PyLong_SHIFT) { - return (char) (((char)-1)*(((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(char) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) - 1 > 2 * PyLong_SHIFT) { - return (char) ((((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(char) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) - 1 > 3 * PyLong_SHIFT) { - return (char) (((char)-1)*(((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(char) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) - 1 > 3 * PyLong_SHIFT) { - return (char) ((((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(char) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) - 1 > 4 * PyLong_SHIFT) { - return (char) (((char)-1)*(((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(char) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(char) - 1 > 4 * PyLong_SHIFT) { - return (char) ((((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); - } - } - break; - } -#endif - if (sizeof(char) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(char, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(char) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(char, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - char val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (char) -1; - } - } else { - char val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (char) -1; - val = __Pyx_PyInt_As_char(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to char"); - return (char) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to char"); - return (char) -1; -} - -/* IsLittleEndian */ -static CYTHON_INLINE int __Pyx_Is_Little_Endian(void) -{ - union { - uint32_t u32; - uint8_t u8[4]; - } S; - S.u32 = 0x01020304; - return S.u8[0] == 4; -} - -/* BufferFormatCheck */ -static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, - __Pyx_BufFmt_StackElem* stack, - __Pyx_TypeInfo* type) { - stack[0].field = &ctx->root; - stack[0].parent_offset = 0; - ctx->root.type = type; - ctx->root.name = "buffer dtype"; - ctx->root.offset = 0; - ctx->head = stack; - ctx->head->field = &ctx->root; - ctx->fmt_offset = 0; - ctx->head->parent_offset = 0; - ctx->new_packmode = '@'; - ctx->enc_packmode = '@'; - ctx->new_count = 1; - ctx->enc_count = 0; - ctx->enc_type = 0; - ctx->is_complex = 0; - ctx->is_valid_array = 0; - ctx->struct_alignment = 0; - while (type->typegroup == 'S') { - ++ctx->head; - ctx->head->field = type->fields; - ctx->head->parent_offset = 0; - type = type->fields->type; - } -} -static int __Pyx_BufFmt_ParseNumber(const char** ts) { - int count; - const char* t = *ts; - if (*t < '0' || *t > '9') { - return -1; - } else { - count = *t++ - '0'; - while (*t >= '0' && *t <= '9') { - count *= 10; - count += *t++ - '0'; - } - } - *ts = t; - return count; -} -static int __Pyx_BufFmt_ExpectNumber(const char **ts) { - int number = __Pyx_BufFmt_ParseNumber(ts); - if (number == -1) - PyErr_Format(PyExc_ValueError,\ - "Does not understand character buffer dtype format string ('%c')", **ts); - return number; -} -static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { - PyErr_Format(PyExc_ValueError, - "Unexpected format string character: '%c'", ch); -} -static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { - switch (ch) { - case '?': return "'bool'"; - case 'c': return "'char'"; - case 'b': return "'signed char'"; - case 'B': return "'unsigned char'"; - case 'h': return "'short'"; - case 'H': return "'unsigned short'"; - case 'i': return "'int'"; - case 'I': return "'unsigned int'"; - case 'l': return "'long'"; - case 'L': return "'unsigned long'"; - case 'q': return "'long long'"; - case 'Q': return "'unsigned long long'"; - case 'f': return (is_complex ? "'complex float'" : "'float'"); - case 'd': return (is_complex ? "'complex double'" : "'double'"); - case 'g': return (is_complex ? "'complex long double'" : "'long double'"); - case 'T': return "a struct"; - case 'O': return "Python object"; - case 'P': return "a pointer"; - case 's': case 'p': return "a string"; - case 0: return "end"; - default: return "unparseable format string"; - } -} -static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return 2; - case 'i': case 'I': case 'l': case 'L': return 4; - case 'q': case 'Q': return 8; - case 'f': return (is_complex ? 8 : 4); - case 'd': return (is_complex ? 16 : 8); - case 'g': { - PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); - return 0; - } - case 'O': case 'P': return sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } -} -static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(short); - case 'i': case 'I': return sizeof(int); - case 'l': case 'L': return sizeof(long); - #ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(PY_LONG_LONG); - #endif - case 'f': return sizeof(float) * (is_complex ? 2 : 1); - case 'd': return sizeof(double) * (is_complex ? 2 : 1); - case 'g': return sizeof(long double) * (is_complex ? 2 : 1); - case 'O': case 'P': return sizeof(void*); - default: { - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } - } -} -typedef struct { char c; short x; } __Pyx_st_short; -typedef struct { char c; int x; } __Pyx_st_int; -typedef struct { char c; long x; } __Pyx_st_long; -typedef struct { char c; float x; } __Pyx_st_float; -typedef struct { char c; double x; } __Pyx_st_double; -typedef struct { char c; long double x; } __Pyx_st_longdouble; -typedef struct { char c; void *x; } __Pyx_st_void_p; -#ifdef HAVE_LONG_LONG -typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; -#endif -static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); - case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); - case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); -#ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); -#endif - case 'f': return sizeof(__Pyx_st_float) - sizeof(float); - case 'd': return sizeof(__Pyx_st_double) - sizeof(double); - case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); - case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } -} -/* These are for computing the padding at the end of the struct to align - on the first member of the struct. This will probably the same as above, - but we don't have any guarantees. - */ -typedef struct { short x; char c; } __Pyx_pad_short; -typedef struct { int x; char c; } __Pyx_pad_int; -typedef struct { long x; char c; } __Pyx_pad_long; -typedef struct { float x; char c; } __Pyx_pad_float; -typedef struct { double x; char c; } __Pyx_pad_double; -typedef struct { long double x; char c; } __Pyx_pad_longdouble; -typedef struct { void *x; char c; } __Pyx_pad_void_p; -#ifdef HAVE_LONG_LONG -typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; -#endif -static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); - case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); - case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); -#ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); -#endif - case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); - case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); - case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); - case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } -} -static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { - switch (ch) { - case 'c': - return 'H'; - case 'b': case 'h': case 'i': - case 'l': case 'q': case 's': case 'p': - return 'I'; - case '?': case 'B': case 'H': case 'I': case 'L': case 'Q': - return 'U'; - case 'f': case 'd': case 'g': - return (is_complex ? 'C' : 'R'); - case 'O': - return 'O'; - case 'P': - return 'P'; - default: { - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } - } -} -static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { - if (ctx->head == NULL || ctx->head->field == &ctx->root) { - const char* expected; - const char* quote; - if (ctx->head == NULL) { - expected = "end"; - quote = ""; - } else { - expected = ctx->head->field->type->name; - quote = "'"; - } - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch, expected %s%s%s but got %s", - quote, expected, quote, - __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); - } else { - __Pyx_StructField* field = ctx->head->field; - __Pyx_StructField* parent = (ctx->head - 1)->field; - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", - field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), - parent->type->name, field->name); - } -} -static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { - char group; - size_t size, offset, arraysize = 1; - if (ctx->enc_type == 0) return 0; - if (ctx->head->field->type->arraysize[0]) { - int i, ndim = 0; - if (ctx->enc_type == 's' || ctx->enc_type == 'p') { - ctx->is_valid_array = ctx->head->field->type->ndim == 1; - ndim = 1; - if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { - PyErr_Format(PyExc_ValueError, - "Expected a dimension of size %zu, got %zu", - ctx->head->field->type->arraysize[0], ctx->enc_count); - return -1; - } - } - if (!ctx->is_valid_array) { - PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", - ctx->head->field->type->ndim, ndim); - return -1; - } - for (i = 0; i < ctx->head->field->type->ndim; i++) { - arraysize *= ctx->head->field->type->arraysize[i]; - } - ctx->is_valid_array = 0; - ctx->enc_count = 1; - } - group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); - do { - __Pyx_StructField* field = ctx->head->field; - __Pyx_TypeInfo* type = field->type; - if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { - size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); - } else { - size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); - } - if (ctx->enc_packmode == '@') { - size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); - size_t align_mod_offset; - if (align_at == 0) return -1; - align_mod_offset = ctx->fmt_offset % align_at; - if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; - if (ctx->struct_alignment == 0) - ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, - ctx->is_complex); - } - if (type->size != size || type->typegroup != group) { - if (type->typegroup == 'C' && type->fields != NULL) { - size_t parent_offset = ctx->head->parent_offset + field->offset; - ++ctx->head; - ctx->head->field = type->fields; - ctx->head->parent_offset = parent_offset; - continue; - } - if ((type->typegroup == 'H' || group == 'H') && type->size == size) { - } else { - __Pyx_BufFmt_RaiseExpected(ctx); - return -1; - } - } - offset = ctx->head->parent_offset + field->offset; - if (ctx->fmt_offset != offset) { - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", - (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); - return -1; - } - ctx->fmt_offset += size; - if (arraysize) - ctx->fmt_offset += (arraysize - 1) * size; - --ctx->enc_count; - while (1) { - if (field == &ctx->root) { - ctx->head = NULL; - if (ctx->enc_count != 0) { - __Pyx_BufFmt_RaiseExpected(ctx); - return -1; - } - break; - } - ctx->head->field = ++field; - if (field->type == NULL) { - --ctx->head; - field = ctx->head->field; - continue; - } else if (field->type->typegroup == 'S') { - size_t parent_offset = ctx->head->parent_offset + field->offset; - if (field->type->fields->type == NULL) continue; - field = field->type->fields; - ++ctx->head; - ctx->head->field = field; - ctx->head->parent_offset = parent_offset; - break; - } else { - break; - } - } - } while (ctx->enc_count); - ctx->enc_type = 0; - ctx->is_complex = 0; - return 0; -} -static PyObject * -__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) -{ - const char *ts = *tsp; - int i = 0, number, ndim; - ++ts; - if (ctx->new_count != 1) { - PyErr_SetString(PyExc_ValueError, - "Cannot handle repeated arrays in format string"); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ndim = ctx->head->field->type->ndim; - while (*ts && *ts != ')') { - switch (*ts) { - case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; - default: break; - } - number = __Pyx_BufFmt_ExpectNumber(&ts); - if (number == -1) return NULL; - if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) - return PyErr_Format(PyExc_ValueError, - "Expected a dimension of size %zu, got %d", - ctx->head->field->type->arraysize[i], number); - if (*ts != ',' && *ts != ')') - return PyErr_Format(PyExc_ValueError, - "Expected a comma in format string, got '%c'", *ts); - if (*ts == ',') ts++; - i++; - } - if (i != ndim) - return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", - ctx->head->field->type->ndim, i); - if (!*ts) { - PyErr_SetString(PyExc_ValueError, - "Unexpected end of format string, expected ')'"); - return NULL; - } - ctx->is_valid_array = 1; - ctx->new_count = 1; - *tsp = ++ts; - return Py_None; -} -static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { - int got_Z = 0; - while (1) { - switch(*ts) { - case 0: - if (ctx->enc_type != 0 && ctx->head == NULL) { - __Pyx_BufFmt_RaiseExpected(ctx); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - if (ctx->head != NULL) { - __Pyx_BufFmt_RaiseExpected(ctx); - return NULL; - } - return ts; - case ' ': - case '\r': - case '\n': - ++ts; - break; - case '<': - if (!__Pyx_Is_Little_Endian()) { - PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); - return NULL; - } - ctx->new_packmode = '='; - ++ts; - break; - case '>': - case '!': - if (__Pyx_Is_Little_Endian()) { - PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); - return NULL; - } - ctx->new_packmode = '='; - ++ts; - break; - case '=': - case '@': - case '^': - ctx->new_packmode = *ts++; - break; - case 'T': - { - const char* ts_after_sub; - size_t i, struct_count = ctx->new_count; - size_t struct_alignment = ctx->struct_alignment; - ctx->new_count = 1; - ++ts; - if (*ts != '{') { - PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_type = 0; - ctx->enc_count = 0; - ctx->struct_alignment = 0; - ++ts; - ts_after_sub = ts; - for (i = 0; i != struct_count; ++i) { - ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); - if (!ts_after_sub) return NULL; - } - ts = ts_after_sub; - if (struct_alignment) ctx->struct_alignment = struct_alignment; - } - break; - case '}': - { - size_t alignment = ctx->struct_alignment; - ++ts; - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_type = 0; - if (alignment && ctx->fmt_offset % alignment) { - ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); - } - } - return ts; - case 'x': - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->fmt_offset += ctx->new_count; - ctx->new_count = 1; - ctx->enc_count = 0; - ctx->enc_type = 0; - ctx->enc_packmode = ctx->new_packmode; - ++ts; - break; - case 'Z': - got_Z = 1; - ++ts; - if (*ts != 'f' && *ts != 'd' && *ts != 'g') { - __Pyx_BufFmt_RaiseUnexpectedChar('Z'); - return NULL; - } - CYTHON_FALLTHROUGH; - case '?': case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': - case 'l': case 'L': case 'q': case 'Q': - case 'f': case 'd': case 'g': - case 'O': case 'p': - if ((ctx->enc_type == *ts) && (got_Z == ctx->is_complex) && - (ctx->enc_packmode == ctx->new_packmode) && (!ctx->is_valid_array)) { - ctx->enc_count += ctx->new_count; - ctx->new_count = 1; - got_Z = 0; - ++ts; - break; - } - CYTHON_FALLTHROUGH; - case 's': - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_count = ctx->new_count; - ctx->enc_packmode = ctx->new_packmode; - ctx->enc_type = *ts; - ctx->is_complex = got_Z; - ++ts; - ctx->new_count = 1; - got_Z = 0; - break; - case ':': - ++ts; - while(*ts != ':') ++ts; - ++ts; - break; - case '(': - if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL; - break; - default: - { - int number = __Pyx_BufFmt_ExpectNumber(&ts); - if (number == -1) return NULL; - ctx->new_count = (size_t)number; - } - } - } -} - -/* TypeInfoCompare */ - static int -__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b) -{ - int i; - if (!a || !b) - return 0; - if (a == b) - return 1; - if (a->size != b->size || a->typegroup != b->typegroup || - a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) { - if (a->typegroup == 'H' || b->typegroup == 'H') { - return a->size == b->size; - } else { - return 0; - } - } - if (a->ndim) { - for (i = 0; i < a->ndim; i++) - if (a->arraysize[i] != b->arraysize[i]) - return 0; - } - if (a->typegroup == 'S') { - if (a->flags != b->flags) - return 0; - if (a->fields || b->fields) { - if (!(a->fields && b->fields)) - return 0; - for (i = 0; a->fields[i].type && b->fields[i].type; i++) { - __Pyx_StructField *field_a = a->fields + i; - __Pyx_StructField *field_b = b->fields + i; - if (field_a->offset != field_b->offset || - !__pyx_typeinfo_cmp(field_a->type, field_b->type)) - return 0; - } - return !a->fields[i].type && !b->fields[i].type; - } - } - return 1; -} - -/* MemviewSliceValidateAndInit */ - static int -__pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec) -{ - if (buf->shape[dim] <= 1) - return 1; - if (buf->strides) { - if (spec & __Pyx_MEMVIEW_CONTIG) { - if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) { - if (unlikely(buf->strides[dim] != sizeof(void *))) { - PyErr_Format(PyExc_ValueError, - "Buffer is not indirectly contiguous " - "in dimension %d.", dim); - goto fail; - } - } else if (unlikely(buf->strides[dim] != buf->itemsize)) { - PyErr_SetString(PyExc_ValueError, - "Buffer and memoryview are not contiguous " - "in the same dimension."); - goto fail; - } - } - if (spec & __Pyx_MEMVIEW_FOLLOW) { - Py_ssize_t stride = buf->strides[dim]; - if (stride < 0) - stride = -stride; - if (unlikely(stride < buf->itemsize)) { - PyErr_SetString(PyExc_ValueError, - "Buffer and memoryview are not contiguous " - "in the same dimension."); - goto fail; - } - } - } else { - if (unlikely(spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1)) { - PyErr_Format(PyExc_ValueError, - "C-contiguous buffer is not contiguous in " - "dimension %d", dim); - goto fail; - } else if (unlikely(spec & (__Pyx_MEMVIEW_PTR))) { - PyErr_Format(PyExc_ValueError, - "C-contiguous buffer is not indirect in " - "dimension %d", dim); - goto fail; - } else if (unlikely(buf->suboffsets)) { - PyErr_SetString(PyExc_ValueError, - "Buffer exposes suboffsets but no strides"); - goto fail; - } - } - return 1; -fail: - return 0; -} -static int -__pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec) -{ - if (spec & __Pyx_MEMVIEW_DIRECT) { - if (unlikely(buf->suboffsets && buf->suboffsets[dim] >= 0)) { - PyErr_Format(PyExc_ValueError, - "Buffer not compatible with direct access " - "in dimension %d.", dim); - goto fail; - } - } - if (spec & __Pyx_MEMVIEW_PTR) { - if (unlikely(!buf->suboffsets || (buf->suboffsets[dim] < 0))) { - PyErr_Format(PyExc_ValueError, - "Buffer is not indirectly accessible " - "in dimension %d.", dim); - goto fail; - } - } - return 1; -fail: - return 0; -} -static int -__pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag) -{ - int i; - if (c_or_f_flag & __Pyx_IS_F_CONTIG) { - Py_ssize_t stride = 1; - for (i = 0; i < ndim; i++) { - if (unlikely(stride * buf->itemsize != buf->strides[i] && buf->shape[i] > 1)) { - PyErr_SetString(PyExc_ValueError, - "Buffer not fortran contiguous."); - goto fail; - } - stride = stride * buf->shape[i]; - } - } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) { - Py_ssize_t stride = 1; - for (i = ndim - 1; i >- 1; i--) { - if (unlikely(stride * buf->itemsize != buf->strides[i] && buf->shape[i] > 1)) { - PyErr_SetString(PyExc_ValueError, - "Buffer not C contiguous."); - goto fail; - } - stride = stride * buf->shape[i]; - } - } - return 1; -fail: - return 0; -} -static int __Pyx_ValidateAndInit_memviewslice( - int *axes_specs, - int c_or_f_flag, - int buf_flags, - int ndim, - __Pyx_TypeInfo *dtype, - __Pyx_BufFmt_StackElem stack[], - __Pyx_memviewslice *memviewslice, - PyObject *original_obj) -{ - struct __pyx_memoryview_obj *memview, *new_memview; - __Pyx_RefNannyDeclarations - Py_buffer *buf; - int i, spec = 0, retval = -1; - __Pyx_BufFmt_Context ctx; - int from_memoryview = __pyx_memoryview_check(original_obj); - __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0); - if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *) - original_obj)->typeinfo)) { - memview = (struct __pyx_memoryview_obj *) original_obj; - new_memview = NULL; - } else { - memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new( - original_obj, buf_flags, 0, dtype); - new_memview = memview; - if (unlikely(!memview)) - goto fail; - } - buf = &memview->view; - if (unlikely(buf->ndim != ndim)) { - PyErr_Format(PyExc_ValueError, - "Buffer has wrong number of dimensions (expected %d, got %d)", - ndim, buf->ndim); - goto fail; - } - if (new_memview) { - __Pyx_BufFmt_Init(&ctx, stack, dtype); - if (unlikely(!__Pyx_BufFmt_CheckString(&ctx, buf->format))) goto fail; - } - if (unlikely((unsigned) buf->itemsize != dtype->size)) { - PyErr_Format(PyExc_ValueError, - "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) " - "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)", - buf->itemsize, - (buf->itemsize > 1) ? "s" : "", - dtype->name, - dtype->size, - (dtype->size > 1) ? "s" : ""); - goto fail; - } - if (buf->len > 0) { - for (i = 0; i < ndim; i++) { - spec = axes_specs[i]; - if (unlikely(!__pyx_check_strides(buf, i, ndim, spec))) - goto fail; - if (unlikely(!__pyx_check_suboffsets(buf, i, ndim, spec))) - goto fail; - } - if (unlikely(buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag))) - goto fail; - } - if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice, - new_memview != NULL) == -1)) { - goto fail; - } - retval = 0; - goto no_fail; -fail: - Py_XDECREF(new_memview); - retval = -1; -no_fail: - __Pyx_RefNannyFinishContext(); - return retval; -} - -/* ObjectToMemviewSlice */ - static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_float_t(PyObject *obj, int writable_flag) { - __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_BufFmt_StackElem stack[1]; - int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_FOLLOW), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) }; - int retcode; - if (obj == Py_None) { - result.memview = (struct __pyx_memoryview_obj *) Py_None; - return result; - } - retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG, - (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT) | writable_flag, 2, - &__Pyx_TypeInfo_nn___pyx_t_5numpy_float_t, stack, - &result, obj); - if (unlikely(retcode == -1)) - goto __pyx_fail; - return result; -__pyx_fail: - result.memview = NULL; - result.data = NULL; - return result; -} - -/* ObjectToMemviewSlice */ - static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_int_t(PyObject *obj, int writable_flag) { - __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_BufFmt_StackElem stack[1]; - int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) }; - int retcode; - if (obj == Py_None) { - result.memview = (struct __pyx_memoryview_obj *) Py_None; - return result; - } - retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0, - PyBUF_RECORDS_RO | writable_flag, 2, - &__Pyx_TypeInfo_nn___pyx_t_5numpy_int_t, stack, - &result, obj); - if (unlikely(retcode == -1)) - goto __pyx_fail; - return result; -__pyx_fail: - result.memview = NULL; - result.data = NULL; - return result; -} - -/* ObjectToMemviewSlice */ - static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float_t(PyObject *obj, int writable_flag) { - __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_BufFmt_StackElem stack[1]; - int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) }; - int retcode; - if (obj == Py_None) { - result.memview = (struct __pyx_memoryview_obj *) Py_None; - return result; - } - retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0, - PyBUF_RECORDS_RO | writable_flag, 1, - &__Pyx_TypeInfo_nn___pyx_t_5numpy_float_t, stack, - &result, obj); - if (unlikely(retcode == -1)) - goto __pyx_fail; - return result; -__pyx_fail: - result.memview = NULL; - result.data = NULL; - return result; -} - -/* ObjectToMemviewSlice */ - static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_d_dc_nn___pyx_t_5numpy_float_t(PyObject *obj, int writable_flag) { - __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_BufFmt_StackElem stack[1]; - int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_FOLLOW), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_FOLLOW), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) }; - int retcode; - if (obj == Py_None) { - result.memview = (struct __pyx_memoryview_obj *) Py_None; - return result; - } - retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG, - (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT) | writable_flag, 3, - &__Pyx_TypeInfo_nn___pyx_t_5numpy_float_t, stack, - &result, obj); - if (unlikely(retcode == -1)) - goto __pyx_fail; - return result; -__pyx_fail: - result.memview = NULL; - result.data = NULL; - return result; -} - -/* ObjectToMemviewSlice */ - static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5numpy_float_t(PyObject *obj, int writable_flag) { - __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_BufFmt_StackElem stack[1]; - int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) }; - int retcode; - if (obj == Py_None) { - result.memview = (struct __pyx_memoryview_obj *) Py_None; - return result; - } - retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0, - PyBUF_RECORDS_RO | writable_flag, 2, - &__Pyx_TypeInfo_nn___pyx_t_5numpy_float_t, stack, - &result, obj); - if (unlikely(retcode == -1)) - goto __pyx_fail; - return result; -__pyx_fail: - result.memview = NULL; - result.data = NULL; - return result; -} - -/* ObjectToMemviewSlice */ - static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int_t(PyObject *obj, int writable_flag) { - __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } }; - __Pyx_BufFmt_StackElem stack[1]; - int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) }; - int retcode; - if (obj == Py_None) { - result.memview = (struct __pyx_memoryview_obj *) Py_None; - return result; - } - retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0, - PyBUF_RECORDS_RO | writable_flag, 1, - &__Pyx_TypeInfo_nn___pyx_t_5numpy_int_t, stack, - &result, obj); - if (unlikely(retcode == -1)) - goto __pyx_fail; - return result; -__pyx_fail: - result.memview = NULL; - result.data = NULL; - return result; -} - -/* CheckBinaryVersion */ - static int __Pyx_check_binary_version(void) { - char ctversion[4], rtversion[4]; - PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); - PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); - if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { - char message[200]; - PyOS_snprintf(message, sizeof(message), - "compiletime version %s of module '%.100s' " - "does not match runtime version %s", - ctversion, __Pyx_MODULE_NAME, rtversion); - return PyErr_WarnEx(NULL, message, 1); - } - return 0; -} - -/* InitStrings */ - static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { - while (t->p) { - #if PY_MAJOR_VERSION < 3 - if (t->is_unicode) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - #else - if (t->is_unicode | t->is_str) { - if (t->intern) { - *t->p = PyUnicode_InternFromString(t->s); - } else if (t->encoding) { - *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); - } else { - *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); - } - } else { - *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); - } - #endif - if (!*t->p) - return -1; - if (PyObject_Hash(*t->p) == -1) - return -1; - ++t; - } - return 0; -} - -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); -} -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { - Py_ssize_t ignore; - return __Pyx_PyObject_AsStringAndSize(o, &ignore); -} -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#if !CYTHON_PEP393_ENABLED -static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - char* defenc_c; - PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); - if (!defenc) return NULL; - defenc_c = PyBytes_AS_STRING(defenc); -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - { - char* end = defenc_c + PyBytes_GET_SIZE(defenc); - char* c; - for (c = defenc_c; c < end; c++) { - if ((unsigned char) (*c) >= 128) { - PyUnicode_AsASCIIString(o); - return NULL; - } - } - } -#endif - *length = PyBytes_GET_SIZE(defenc); - return defenc_c; -} -#else -static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - if (likely(PyUnicode_IS_ASCII(o))) { - *length = PyUnicode_GET_LENGTH(o); - return PyUnicode_AsUTF8(o); - } else { - PyUnicode_AsASCIIString(o); - return NULL; - } -#else - return PyUnicode_AsUTF8AndSize(o, length); -#endif -} -#endif -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT - if ( -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - __Pyx_sys_getdefaultencoding_not_ascii && -#endif - PyUnicode_Check(o)) { - return __Pyx_PyUnicode_AsStringAndSize(o, length); - } else -#endif -#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - if (PyByteArray_Check(o)) { - *length = PyByteArray_GET_SIZE(o); - return PyByteArray_AS_STRING(o); - } else -#endif - { - char* result; - int r = PyBytes_AsStringAndSize(o, &result, length); - if (unlikely(r < 0)) { - return NULL; - } else { - return result; - } - } -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - int is_true = x == Py_True; - if (is_true | (x == Py_False) | (x == Py_None)) return is_true; - else return PyObject_IsTrue(x); -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { - int retval; - if (unlikely(!x)) return -1; - retval = __Pyx_PyObject_IsTrue(x); - Py_DECREF(x); - return retval; -} -static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { -#if PY_MAJOR_VERSION >= 3 - if (PyLong_Check(result)) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) { - Py_DECREF(result); - return NULL; - } - return result; - } -#endif - PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type %.200s)", - type_name, type_name, Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { -#if CYTHON_USE_TYPE_SLOTS - PyNumberMethods *m; -#endif - const char *name = NULL; - PyObject *res = NULL; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x) || PyLong_Check(x))) -#else - if (likely(PyLong_Check(x))) -#endif - return __Pyx_NewRef(x); -#if CYTHON_USE_TYPE_SLOTS - m = Py_TYPE(x)->tp_as_number; - #if PY_MAJOR_VERSION < 3 - if (m && m->nb_int) { - name = "int"; - res = m->nb_int(x); - } - else if (m && m->nb_long) { - name = "long"; - res = m->nb_long(x); - } - #else - if (likely(m && m->nb_int)) { - name = "int"; - res = m->nb_int(x); - } - #endif -#else - if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { - res = PyNumber_Int(x); - } -#endif - if (likely(res)) { -#if PY_MAJOR_VERSION < 3 - if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { -#else - if (unlikely(!PyLong_CheckExact(res))) { -#endif - return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); - } - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - } - return res; -} -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject *x; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(b))) { - if (sizeof(Py_ssize_t) >= sizeof(long)) - return PyInt_AS_LONG(b); - else - return PyInt_AsSsize_t(b); - } -#endif - if (likely(PyLong_CheckExact(b))) { - #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)b)->ob_digit; - const Py_ssize_t size = Py_SIZE(b); - if (likely(__Pyx_sst_abs(size) <= 1)) { - ival = likely(size) ? digits[0] : 0; - if (size == -1) ival = -ival; - return ival; - } else { - switch (size) { - case 2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - } - } - #endif - return PyLong_AsSsize_t(b); - } - x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { - return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); -} -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { - return PyInt_FromSize_t(ival); -} - - -#endif /* Py_PYTHON_H */ diff --git a/tests/coord_cython.pyx b/tests/coord_cython.pyx deleted file mode 100644 index 1c8d2861..00000000 --- a/tests/coord_cython.pyx +++ /dev/null @@ -1,273 +0,0 @@ -# coding: utf-8 - -#from __future__ import division, unicode_literals - -""" -Utilities for manipulating coordinates or list of coordinates, under periodic -boundary conditions or otherwise. -""" - -from six.moves import zip - -__author__ = "Will Richards" -__copyright__ = "Copyright 2011, The Materials Project" -__version__ = "1.0" -__maintainer__ = "Will Richards" -__email__ = "wmdrichards@gmail.com" -__date__ = "Nov 27, 2011" - -import numpy as np - -from libc.stdlib cimport malloc, free -from libc.math cimport round, fabs, sqrt, acos, M_PI, cos, sin -cimport numpy as np -cimport cython - -#create images, 2d array of all length 3 combinations of [-1,0,1] -r = np.arange(-1, 2, dtype=np.float_) -arange = r[:, None] * np.array([1, 0, 0])[None, :] -brange = r[:, None] * np.array([0, 1, 0])[None, :] -crange = r[:, None] * np.array([0, 0, 1])[None, :] -images_t = arange[:, None, None] + brange[None, :, None] + \ - crange[None, None, :] -images = images_t.reshape((27, 3)) - -cdef np.float_t[:, ::1] images_view = images - -@cython.boundscheck(False) -@cython.wraparound(False) -cdef void dot_2d(np.float_t[:, ::1] a, np.float_t[:, ::1] b, np.float_t[:, ::1] o) nogil: - cdef int i, j, k, I, J, K - I = a.shape[0] - J = b.shape[1] - K = a.shape[1] - - for j in range(J): - for i in range(I): - o[i, j] = 0 - for k in range(K): - for i in range(I): - o[i, j] += a[i, k] * b[k, j] - -@cython.boundscheck(False) -@cython.wraparound(False) -cdef void dot_2d_mod(np.float_t[:, ::1] a, np.float_t[:, ::1] b, np.float_t[:, ::1] o) nogil: - cdef int i, j, k, I, J, K - I = a.shape[0] - J = b.shape[1] - K = a.shape[1] - - for j in range(J): - for i in range(I): - o[i, j] = 0 - for k in range(K): - for i in range(I): - o[i, j] += a[i, k] % 1 * b[k, j] - -@cython.boundscheck(False) -@cython.wraparound(False) -@cython.initializedcheck(False) -def pbc_shortest_vectors(lattice, fcoords1, fcoords2, mask=None, return_d2=False, lll_frac_tol=None): - """ - Returns the shortest vectors between two lists of coordinates taking into - account periodic boundary conditions and the lattice. - - Args: - lattice: lattice to use - fcoords1: First set of fractional coordinates. e.g., [0.5, 0.6, 0.7] - or [[1.1, 1.2, 4.3], [0.5, 0.6, 0.7]]. Must be np.float_ - fcoords2: Second set of fractional coordinates. - mask (int_ array): Mask of matches that are not allowed. - i.e. if mask[1,2] == True, then subset[1] cannot be matched - to superset[2] - lll_frac_tol (float_ array of length 3): Fractional tolerance (per LLL lattice vector) over which - the calculation of minimum vectors will be skipped. - Can speed up calculation considerably for large structures. - - Returns: - array of displacement vectors from fcoords1 to fcoords2 - first index is fcoords1 index, second is fcoords2 index - """ - - #ensure correct shape - fcoords1, fcoords2 = np.atleast_2d(fcoords1, fcoords2) - - - fcoords1 = lattice.get_lll_frac_coords(fcoords1) - fcoords2 = lattice.get_lll_frac_coords(fcoords2) - - cdef np.float_t[:, ::1] lat = np.array(lattice.lll_matrix, dtype=np.float_, copy=False, order='C') - - cdef int i, j, k, l, I, J, bestK - - I = len(fcoords1) - J = len(fcoords2) - - cdef np.float_t[:, ::1] fc1 = fcoords1 - cdef np.float_t[:, ::1] fc2 = fcoords2 - - cdef np.float_t[:, ::1] cart_f1 = malloc(3 * I * sizeof(np.float_t)) - cdef np.float_t[:, ::1] cart_f2 = malloc(3 * J * sizeof(np.float_t)) - cdef np.float_t[:, ::1] cart_im = malloc(81 * sizeof(np.float_t)) - - cdef bint has_mask = mask is not None - cdef np.int_t[:, :] m - if has_mask: - m = np.array(mask, dtype=np.int_, copy=False, order='C') - - cdef bint has_ftol = (lll_frac_tol is not None) - cdef np.float_t[:] ftol - if has_ftol: - ftol = np.array(lll_frac_tol, dtype=np.float_, order='C', copy=False) - - - dot_2d_mod(fc1, lat, cart_f1) - dot_2d_mod(fc2, lat, cart_f2) - dot_2d(images_view, lat, cart_im) - - vectors = np.empty((I, J, 3)) - d2 = np.empty((I, J)) - cdef np.float_t[:, :, ::1] vs = vectors - cdef np.float_t[:, ::1] ds = d2 - cdef np.float_t best, d, inc_d, da, db, dc, fdist - cdef bint within_frac = True - cdef np.float_t[:] pre_im = malloc(3 * sizeof(np.float_t)) - - for i in range(I): - for j in range(J): - within_frac = False - if (not has_mask) or (m[i, j] == 0): - within_frac = True - if has_ftol: - for l in range(3): - fdist = fc2[j, l] - fc1[i, l] - if fabs(fdist - round(fdist)) > ftol[l]: - within_frac = False - break - if within_frac: - for l in range(3): - pre_im[l] = cart_f2[j, l] - cart_f1[i, l] - best = 1e100 - for k in range(27): - # compilers have a hard time unrolling this - da = pre_im[0] + cart_im[k, 0] - db = pre_im[1] + cart_im[k, 1] - dc = pre_im[2] + cart_im[k, 2] - d = da * da + db * db + dc * dc - if d < best: - best = d - bestk = k - ds[i, j] = best - for l in range(3): - vs[i, j, l] = pre_im[l] + cart_im[bestk, l] - if not within_frac: - ds[i, j] = 1e20 - for l in range(3): - vs[i, j, l] = 1e20 - - free(&cart_f1[0,0]) - free(&cart_f2[0,0]) - free(&cart_im[0,0]) - free(&pre_im[0]) - - if return_d2: - return vectors, d2 - else: - return vectors - -@cython.boundscheck(False) -@cython.wraparound(False) -@cython.initializedcheck(False) -def is_coord_subset_pbc(subset, superset, atol, mask): - """ - Tests if all fractional coords in subset are contained in superset. - Allows specification of a mask determining pairs that are not - allowed to match to each other - - Args: - subset, superset: List of fractional coords - - Returns: - True if all of subset is in superset. - """ - - cdef np.float_t[:, :] fc1 = subset - cdef np.float_t[:, :] fc2 = superset - cdef np.float_t[:] t = atol - cdef np.int_t[:, :] m = np.array(mask, dtype=np.int_, copy=False, order='C') - - cdef int i, j, k, I, J - cdef np.float_t d - cdef bint ok - - I = fc1.shape[0] - J = fc2.shape[0] - - for i in range(I): - ok = False - for j in range(J): - if m[i, j]: - continue - ok = True - for k in range(3): - d = fc1[i, k] - fc2[j, k] - if fabs(d - round(d)) > t[k]: - ok = False - break - if ok: - break - if not ok: - break - return bool(ok) - -@cython.boundscheck(False) -@cython.wraparound(False) -@cython.initializedcheck(False) -def coord_list_mapping_pbc(subset, superset, atol=1e-8): - """ - Gives the index mapping from a subset to a superset. - Superset cannot contain duplicate matching rows - - Args: - subset, superset: List of frac_coords - - Returns: - list of indices such that superset[indices] = subset - """ - inds = np.zeros(len(subset), dtype=np.int) - 1 - subset = np.atleast_2d(subset) - superset = np.atleast_2d(superset) - - cdef np.float_t[:, :] fc1 = subset - cdef np.float_t[:, :] fc2 = superset - cdef np.float_t[:] t = atol - cdef np.int_t[:] c_inds = inds - cdef np.float_t d - cdef bint ok_inner, ok_outer - - I = fc1.shape[0] - J = fc2.shape[0] - - for i in range(I): - ok_outer = False - for j in range(J): - ok_inner = True - for k in range(3): - d = fc1[i, k] - fc2[j, k] - if fabs(d - round(d)) > t[k]: - ok_inner = False - break - if ok_inner: - if c_inds[i] >= 0: - raise ValueError("Something wrong with the inputs, likely duplicates " - "in superset") - c_inds[i] = j - ok_outer = True - # we don't break here so we can check for duplicates in superset - if not ok_outer: - break - - if not ok_outer: - raise ValueError("subset is not a subset of superset") - - return inds \ No newline at end of file diff --git a/tests/coords.py b/tests/coords.py deleted file mode 100644 index b6784dff..00000000 --- a/tests/coords.py +++ /dev/null @@ -1,504 +0,0 @@ -__author__ = "https://github.com/materialsproject/pymatgen/blob/d45fdc1d9930d7952a26de51aab0d5b92fd27236/pymatgen/util/coord.py" -__version__ = "0.1.0" - - -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project 0 - - -def is_coord_subset(subset, superset, atol=1e-8): - """ - Tests if all coords in subset are contained in superset. - Doesn't use periodic boundary conditions - - Args: - subset, superset: List of coords - - Returns: - True if all of subset is in superset. - """ - c1 = np.array(subset) - c2 = np.array(superset) - is_close = np.all(np.abs(c1[:, None, :] - c2[None, :, :]) < atol, axis=-1) - any_close = np.any(is_close, axis=-1) - return np.all(any_close) - - -def coord_list_mapping(subset, superset, atol=1e-8): - """ - Gives the index mapping from a subset to a superset. - Subset and superset cannot contain duplicate rows - - Args: - subset, superset: List of coords - - Returns: - list of indices such that superset[indices] = subset - """ - c1 = np.array(subset) - c2 = np.array(superset) - inds = np.where( - np.all(np.isclose(c1[:, None, :], c2[None, :, :], atol=atol), axis=2) - )[1] - result = c2[inds] - if not np.allclose(c1, result, atol=atol): - if not is_coord_subset(subset, superset): - raise ValueError("subset is not a subset of superset") - if not result.shape == c1.shape: - raise ValueError( - "Something wrong with the inputs, likely duplicates " "in superset" - ) - return inds - - -def coord_list_mapping_pbc(subset, superset, atol=1e-8): - """ - Gives the index mapping from a subset to a superset. - Superset cannot contain duplicate matching rows - - Args: - subset, superset: List of frac_coords - - Returns: - list of indices such that superset[indices] = subset - """ - # pylint: disable=I1101 - atol = np.array([1.0, 1.0, 1.0]) * atol - return cuc.coord_list_mapping_pbc(subset, superset, atol) - - -def get_linear_interpolated_value(x_values, y_values, x): - """ - Returns an interpolated value by linear interpolation between two values. - This method is written to avoid dependency on scipy, which causes issues on - threading servers. - - Args: - x_values: Sequence of x values. - y_values: Corresponding sequence of y values - x: Get value at particular x - - Returns: - Value at x. - """ - a = np.array(sorted(zip(x_values, y_values), key=lambda d: d[0])) - - ind = np.where(a[:, 0] >= x)[0] - - if len(ind) == 0 or ind[0] == 0: - raise ValueError("x is out of range of provided x_values") - - i = ind[0] - x1, x2 = a[i - 1][0], a[i][0] - y1, y2 = a[i - 1][1], a[i][1] - - return y1 + (y2 - y1) / (x2 - x1) * (x - x1) - - -def all_distances(coords1, coords2): - """ - Returns the distances between two lists of coordinates - - Args: - coords1: First set of cartesian coordinates. - coords2: Second set of cartesian coordinates. - - Returns: - 2d array of cartesian distances. E.g the distance between - coords1[i] and coords2[j] is distances[i,j] - """ - c1 = np.array(coords1) - c2 = np.array(coords2) - z = (c1[:, None, :] - c2[None, :, :]) ** 2 - return np.sum(z, axis=-1) ** 0.5 - - -def pbc_diff(fcoords1, fcoords2): - """ - Returns the 'fractional distance' between two coordinates taking into - account periodic boundary conditions. - - Args: - fcoords1: First set of fractional coordinates. e.g., [0.5, 0.6, - 0.7] or [[1.1, 1.2, 4.3], [0.5, 0.6, 0.7]]. It can be a single - coord or any array of coords. - fcoords2: Second set of fractional coordinates. - - Returns: - Fractional distance. Each coordinate must have the property that - abs(a) <= 0.5. Examples: - pbc_diff([0.1, 0.1, 0.1], [0.3, 0.5, 0.9]) = [-0.2, -0.4, 0.2] - pbc_diff([0.9, 0.1, 1.01], [0.3, 0.5, 0.9]) = [-0.4, -0.4, 0.11] - """ - fdist = np.subtract(fcoords1, fcoords2) - return fdist - np.round(fdist) - - -def pbc_shortest_vectors(lattice, fcoords1, fcoords2, mask=None, return_d2=False): - """ - Returns the shortest vectors between two lists of coordinates taking into - account periodic boundary conditions and the lattice. - - Args: - lattice: lattice to use - fcoords1: First set of fractional coordinates. e.g., [0.5, 0.6, 0.7] - or [[1.1, 1.2, 4.3], [0.5, 0.6, 0.7]]. It can be a single - coord or any array of coords. - fcoords2: Second set of fractional coordinates. - mask (boolean array): Mask of matches that are not allowed. - i.e. if mask[1,2] == True, then subset[1] cannot be matched - to superset[2] - return_d2 (boolean): whether to also return the squared distances - - Returns: - array of displacement vectors from fcoords1 to fcoords2 - first index is fcoords1 index, second is fcoords2 index - """ - # pylint: disable=I1101 - return cuc.pbc_shortest_vectors(lattice, fcoords1, fcoords2, mask, return_d2) - - -def find_in_coord_list_pbc(fcoord_list, fcoord, atol=1e-8): - """ - Get the indices of all points in a fractional coord list that are - equal to a fractional coord (with a tolerance), taking into account - periodic boundary conditions. - - Args: - fcoord_list: List of fractional coords - fcoord: A specific fractional coord to test. - atol: Absolute tolerance. Defaults to 1e-8. - - Returns: - Indices of matches, e.g., [0, 1, 2, 3]. Empty list if not found. - """ - if len(fcoord_list) == 0: - return [] - fcoords = np.tile(fcoord, (len(fcoord_list), 1)) - fdist = fcoord_list - fcoords - fdist -= np.round(fdist) - return np.where(np.all(np.abs(fdist) < atol, axis=1))[0] - - -def in_coord_list_pbc(fcoord_list, fcoord, atol=1e-8): - """ - Tests if a particular fractional coord is within a fractional coord_list. - - Args: - fcoord_list: List of fractional coords to test - fcoord: A specific fractional coord to test. - atol: Absolute tolerance. Defaults to 1e-8. - - Returns: - True if coord is in the coord list. - """ - return len(find_in_coord_list_pbc(fcoord_list, fcoord, atol=atol)) > 0 - - -def is_coord_subset_pbc(subset, superset, atol=1e-8, mask=None): - """ - Tests if all fractional coords in subset are contained in superset. - - Args: - subset, superset: List of fractional coords - atol (float or size 3 array): Tolerance for matching - mask (boolean array): Mask of matches that are not allowed. - i.e. if mask[1,2] == True, then subset[1] cannot be matched - to superset[2] - - Returns: - True if all of subset is in superset. - """ - # pylint: disable=I1101 - c1 = np.array(subset, dtype=np.float64) - c2 = np.array(superset, dtype=np.float64) - if mask is not None: - m = np.array(mask, dtype=np.int) - else: - m = np.zeros((len(subset), len(superset)), dtype=np.int) - atol = np.zeros(3, dtype=np.float64) + atol - return cuc.is_coord_subset_pbc(c1, c2, atol, m) - - -def lattice_points_in_supercell(supercell_matrix): - """ - Returns the list of points on the original lattice contained in the - supercell in fractional coordinates (with the supercell basis). - e.g. [[2,0,0],[0,1,0],[0,0,1]] returns [[0,0,0],[0.5,0,0]] - - Args: - supercell_matrix: 3x3 matrix describing the supercell - - Returns: - numpy array of the fractional coordinates - """ - diagonals = np.array( - [ - [0, 0, 0], - [0, 0, 1], - [0, 1, 0], - [0, 1, 1], - [1, 0, 0], - [1, 0, 1], - [1, 1, 0], - [1, 1, 1], - ] - ) - d_points = np.dot(diagonals, supercell_matrix) - - mins = np.min(d_points, axis=0) - maxes = np.max(d_points, axis=0) + 1 - - ar = np.arange(mins[0], maxes[0])[:, None] * np.array([1, 0, 0])[None, :] - br = np.arange(mins[1], maxes[1])[:, None] * np.array([0, 1, 0])[None, :] - cr = np.arange(mins[2], maxes[2])[:, None] * np.array([0, 0, 1])[None, :] - - all_points = ar[:, None, None] + br[None, :, None] + cr[None, None, :] - all_points = all_points.reshape((-1, 3)) - - frac_points = np.dot(all_points, np.linalg.inv(supercell_matrix)) - - tvects = frac_points[ - np.all(frac_points < 1 - 1e-10, axis=1) & np.all(frac_points >= -1e-10, axis=1) - ] - assert len(tvects) == round(abs(np.linalg.det(supercell_matrix))) - return tvects - - -def barycentric_coords(coords, simplex): - """ - Converts a list of coordinates to barycentric coordinates, given a - simplex with d+1 points. Only works for d >= 2. - - Args: - coords: list of n coords to transform, shape should be (n,d) - simplex: list of coordinates that form the simplex, shape should be - (d+1, d) - - Returns: - a LIST of barycentric coordinates (even if the original input was 1d) - """ - coords = np.atleast_2d(coords) - - t = np.transpose(simplex[:-1, :]) - np.transpose(simplex[-1, :])[:, None] - all_but_one = np.transpose(np.linalg.solve(t, np.transpose(coords - simplex[-1]))) - last_coord = 1 - np.sum(all_but_one, axis=-1)[:, None] - return np.append(all_but_one, last_coord, axis=-1) - - -def get_angle(v1, v2, units="degrees"): - """ - Calculates the angle between two vectors. - - Args: - v1: Vector 1 - v2: Vector 2 - units: "degrees" or "radians". Defaults to "degrees". - - Returns: - Angle between them in degrees. - """ - d = np.dot(v1, v2) / np.linalg.norm(v1) / np.linalg.norm(v2) - d = min(d, 1) - d = max(d, -1) - angle = math.acos(d) - if units == "degrees": - return math.degrees(angle) - if units == "radians": - return angle - raise ValueError("Invalid units {}".format(units)) - - -class Simplex: - """ - A generalized simplex object. See http://en.wikipedia.org/wiki/Simplex. - - .. attribute: space_dim - - Dimension of the space. Usually, this is 1 more than the simplex_dim. - - .. attribute: simplex_dim - - Dimension of the simplex coordinate space. - """ - - def __init__(self, coords): - """ - Initializes a Simplex from vertex coordinates. - - Args: - coords ([[float]]): Coords of the vertices of the simplex. E.g., - [[1, 2, 3], [2, 4, 5], [6, 7, 8], [8, 9, 10]. - """ - self._coords = np.array(coords) - self.space_dim, self.simplex_dim = self._coords.shape - self.origin = self._coords[-1] - if self.space_dim == self.simplex_dim + 1: - # precompute augmented matrix for calculating bary_coords - self._aug = np.concatenate([coords, np.ones((self.space_dim, 1))], axis=-1) - self._aug_inv = np.linalg.inv(self._aug) - - @property - def volume(self): - """ - Volume of the simplex. - """ - return abs(np.linalg.det(self._aug)) / math.factorial(self.simplex_dim) - - def bary_coords(self, point): - """ - Args: - point (): Point coordinates. - - Returns: - Barycentric coordinations. - """ - try: - return np.dot(np.concatenate([point, [1]]), self._aug_inv) - except AttributeError: - raise ValueError("Simplex is not full-dimensional") - - def point_from_bary_coords(self, bary_coords): - """ - Args: - bary_coords (): Barycentric coordinates - - Returns: - Point coordinates - """ - try: - return np.dot(bary_coords, self._aug[:, :-1]) - except AttributeError: - raise ValueError("Simplex is not full-dimensional") - - def in_simplex(self, point, tolerance=1e-8): - """ - Checks if a point is in the simplex using the standard barycentric - coordinate system algorithm. - - Taking an arbitrary vertex as an origin, we compute the basis for the - simplex from this origin by subtracting all other vertices from the - origin. We then project the point into this coordinate system and - determine the linear decomposition coefficients in this coordinate - system. If the coeffs satisfy that all coeffs >= 0, the composition - is in the facet. - - Args: - point ([float]): Point to test - tolerance (float): Tolerance to test if point is in simplex. - """ - return (self.bary_coords(point) >= -tolerance).all() - - def line_intersection(self, point1, point2, tolerance=1e-8): - """ - Computes the intersection points of a line with a simplex - Args: - point1, point2 ([float]): Points that determine the line - Returns: - points where the line intersects the simplex (0, 1, or 2) - """ - b1 = self.bary_coords(point1) - b2 = self.bary_coords(point2) - l = b1 - b2 - # don't use barycentric dimension where line is parallel to face - valid = np.abs(l) > 1e-10 - # array of all the barycentric coordinates on the line where - # one of the values is 0 - possible = b1 - (b1[valid] / l[valid])[:, None] * l - barys = [] - for p in possible: - # it's only an intersection if its in the simplex - if (p >= -tolerance).all(): - found = False - # don't return duplicate points - for b in barys: - if np.all(np.abs(b - p) < tolerance): - found = True - break - if not found: - barys.append(p) - assert len(barys) < 3 - return [self.point_from_bary_coords(b) for b in barys] - - def __eq__(self, other): - for p in itertools.permutations(self._coords): - if np.allclose(p, other.coords): - return True - return False - - def __hash__(self): - return len(self._coords) - - def __repr__(self): - output = [ - "{}-simplex in {}D space".format(self.simplex_dim, self.space_dim), - "Vertices:", - ] - for coord in self._coords: - output.append("\t({})".format(", ".join(map(str, coord)))) - return "\n".join(output) - - def __str__(self): - return self.__repr__() - - @property - def coords(self): - """ - Returns a copy of the vertex coordinates in the simplex. - """ - return self._coords.copy() diff --git a/tests/integration_tests/fitting/test_fitter.py b/tests/integration/fitting/test_fitter.py similarity index 83% rename from tests/integration_tests/fitting/test_fitter.py rename to tests/integration/fitting/test_fitter.py index d5c9b255..c6d130fd 100644 --- a/tests/integration_tests/fitting/test_fitter.py +++ b/tests/integration/fitting/test_fitter.py @@ -1,16 +1,15 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause +import numpy as np import pytest -import numpy as np -from easyscience import Fitter from easyscience import AvailableMinimizers +from easyscience import Fitter from easyscience import ObjBase from easyscience import Parameter -from easyscience.fitting.minimizers import FitError from easyscience.base_classes import ModelBase +from easyscience.fitting.minimizers import FitError # Model and container of parameters for tests @@ -19,9 +18,9 @@ class AbsSin(ObjBase): offset: Parameter def __init__(self, offset_val: float, phase_val: float): - offset = Parameter("offset", offset_val) - phase = Parameter("phase", phase_val) - super().__init__("sin", offset=offset, phase=phase) + offset = Parameter('offset', offset_val) + phase = Parameter('phase', phase_val) + super().__init__('sin', offset=offset, phase=phase) def __call__(self, x): return np.abs(np.sin(self.phase.value * x + self.offset.value)) @@ -32,9 +31,9 @@ class AbsSin2D(ObjBase): offset: Parameter def __init__(self, offset_val: float, phase_val: float): - offset = Parameter("offset", offset_val) - phase = Parameter("phase", phase_val) - super().__init__("sin2D", offset=offset, phase=phase) + offset = Parameter('offset', offset_val) + phase = Parameter('phase', phase_val) + super().__init__('sin2D', offset=offset, phase=phase) def __call__(self, x): X = x[:, :, 0] # x is a 2D array @@ -56,8 +55,8 @@ def __call__(self, x): class StraightLine(ModelBase): def __init__(self, slope: float, intercept: float): super().__init__() - self._slope = Parameter("slope", slope) - self._intercept = Parameter("intercept", intercept) + self._slope = Parameter('slope', slope) + self._intercept = Parameter('intercept', intercept) @property def slope(self) -> Parameter: @@ -84,14 +83,12 @@ def check_fit_results(result, sp_sin, ref_sin, x, **kwargs): assert result.chi2 == pytest.approx(0, abs=1.5e-3 * (len(result.x) - result.n_pars)) assert result.reduced_chi == pytest.approx(0, abs=1.5e-3) assert result.success - if "sp_ref1" in kwargs.keys(): - sp_ref1 = kwargs["sp_ref1"] + if 'sp_ref1' in kwargs.keys(): + sp_ref1 = kwargs['sp_ref1'] for key, value in sp_ref1.items(): assert key in result.p.keys() assert key in result.p0.keys() - assert result.p0[key] == pytest.approx( - value - ) # Bumps does something strange here + assert result.p0[key] == pytest.approx(value) # Bumps does something strange here assert np.all(result.x == x) for item1, item2 in zip(sp_sin._kwargs.values(), ref_sin._kwargs.values()): # assert item.error > 0 % This does not work as some methods don't calculate error @@ -102,8 +99,9 @@ def check_fit_results(result, sp_sin, ref_sin, x, **kwargs): assert result.residual == pytest.approx(sp_sin(x) - y_calc_ref, abs=1e-2) +@pytest.mark.fast @pytest.mark.parametrize( - "fit_engine", + 'fit_engine', [ None, AvailableMinimizers.LMFit, @@ -127,7 +125,7 @@ def test_basic_fit(fit_engine: AvailableMinimizers): try: f.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') result = f.fit(x=x, y=y, weights=weights) @@ -139,8 +137,9 @@ def test_basic_fit(fit_engine: AvailableMinimizers): assert sp_sin.offset.value == pytest.approx(ref_sin.offset.value, rel=1e-3) +@pytest.mark.fast @pytest.mark.parametrize( - "fit_engine", + 'fit_engine', [ None, AvailableMinimizers.LMFit, @@ -160,11 +159,11 @@ def test_fit_result(fit_engine): sp_sin.phase.fixed = False sp_ref1 = { - f"p{item1.unique_name}": item1.value + f'p{item1.unique_name}': item1.value for item1, item2 in zip(sp_sin._kwargs.values(), ref_sin._kwargs.values()) } sp_ref2 = { - f"p{item1.unique_name}": item2.value + f'p{item1.unique_name}': item2.value for item1, item2 in zip(sp_sin._kwargs.values(), ref_sin._kwargs.values()) } @@ -174,14 +173,15 @@ def test_fit_result(fit_engine): try: f.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') result = f.fit(x, y, weights=weights) check_fit_results(result, sp_sin, ref_sin, x, sp_ref1=sp_ref1, sp_ref2=sp_ref2) +@pytest.mark.fast @pytest.mark.parametrize( - "fit_engine", + 'fit_engine', [ None, AvailableMinimizers.LMFit, @@ -205,7 +205,7 @@ def test_basic_max_evaluations(fit_engine): try: f.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') f.max_evaluations = 3 try: result = f.fit(x=x, y=y, weights=weights) @@ -214,11 +214,12 @@ def test_basic_max_evaluations(fit_engine): assert sp_sin.offset.value != pytest.approx(ref_sin.offset.value, rel=1e-3) except FitError as e: # DFO throws a different error - assert "Objective has been called MAXFUN times" in str(e) + assert 'Objective has been called MAXFUN times' in str(e) +@pytest.mark.fast @pytest.mark.parametrize( - "fit_engine,tolerance", + 'fit_engine,tolerance', [ (None, 10), (AvailableMinimizers.LMFit, 10), @@ -242,7 +243,7 @@ def test_basic_tolerance(fit_engine, tolerance): try: f.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') f.tolerance = tolerance result = f.fit(x=x, y=y, weights=weights) # Result should not be the same as the reference @@ -250,7 +251,8 @@ def test_basic_tolerance(fit_engine, tolerance): assert sp_sin.offset.value != pytest.approx(ref_sin.offset.value, rel=1e-3) -@pytest.mark.parametrize("fit_method", ["leastsq", "powell", "cobyla"]) +@pytest.mark.fast +@pytest.mark.parametrize('fit_method', ['leastsq', 'powell', 'cobyla']) def test_lmfit_methods(fit_method): ref_sin = AbsSin(0.2, np.pi) sp_sin = AbsSin(0.354, 3.05) @@ -269,7 +271,8 @@ def test_lmfit_methods(fit_method): # @pytest.mark.xfail(reason="known bumps issue") -@pytest.mark.parametrize("fit_method", ["newton", "lm"]) +@pytest.mark.fast +@pytest.mark.parametrize('fit_method', ['newton', 'lm']) def test_bumps_methods(fit_method): ref_sin = AbsSin(0.2, np.pi) sp_sin = AbsSin(0.354, 3.05) @@ -282,14 +285,15 @@ def test_bumps_methods(fit_method): sp_sin.phase.fixed = False f = Fitter(sp_sin, sp_sin) - f.switch_minimizer("Bumps") + f.switch_minimizer('Bumps') assert fit_method in f._minimizer.supported_methods() result = f.fit(x, y, weights=weights, method=fit_method) check_fit_results(result, sp_sin, ref_sin, x) +@pytest.mark.fast @pytest.mark.parametrize( - "fit_engine", + 'fit_engine', [AvailableMinimizers.LMFit, AvailableMinimizers.Bumps, AvailableMinimizers.DFO], ) def test_dependent_parameter(fit_engine): @@ -303,21 +307,22 @@ def test_dependent_parameter(fit_engine): f = Fitter(sp_sin, sp_sin) sp_sin.offset.make_dependent_on( - dependency_expression="2*phase", dependency_map={"phase": sp_sin.phase} + dependency_expression='2*phase', dependency_map={'phase': sp_sin.phase} ) if fit_engine is not None: try: f.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') result = f.fit(x, y, weights=weights) check_fit_results(result, sp_sin, ref_sin, x) +@pytest.mark.fast @pytest.mark.parametrize( - "fit_engine", + 'fit_engine', [ None, AvailableMinimizers.LMFit, @@ -337,12 +342,12 @@ def test_2D_vectorized(fit_engine): try: ff.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') try: result = ff.fit(x=XY, y=mm(XY), weights=weights, vectorized=True) except FitError as e: - if "Unable to allocate" in str(e): - pytest.skip(msg="MemoryError - Matrix too large") + if 'Unable to allocate' in str(e): + pytest.skip(msg='MemoryError - Matrix too large') else: raise e assert result.n_pars == len(m2.get_fit_parameters()) @@ -354,8 +359,9 @@ def test_2D_vectorized(fit_engine): assert result.residual == pytest.approx(mm(XY) - y_calc_ref, abs=1e-2) +@pytest.mark.fast @pytest.mark.parametrize( - "fit_engine", + 'fit_engine', [ None, AvailableMinimizers.LMFit, @@ -375,14 +381,12 @@ def test_2D_non_vectorized(fit_engine): try: ff.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') try: - result = ff.fit( - x=XY, y=mm(XY.reshape(-1, 2)), weights=weights, vectorized=False - ) + result = ff.fit(x=XY, y=mm(XY.reshape(-1, 2)), weights=weights, vectorized=False) except FitError as e: - if "Unable to allocate" in str(e): - pytest.skip(msg="MemoryError - Matrix too large") + if 'Unable to allocate' in str(e): + pytest.skip(msg='MemoryError - Matrix too large') else: raise e assert result.n_pars == len(m2.get_fit_parameters()) @@ -391,13 +395,12 @@ def test_2D_non_vectorized(fit_engine): assert np.all(result.x == XY) y_calc_ref = m2(XY.reshape(-1, 2)) assert result.y_calc == pytest.approx(y_calc_ref, abs=1e-2) - assert result.residual == pytest.approx( - mm(XY.reshape(-1, 2)) - y_calc_ref, abs=1e-2 - ) + assert result.residual == pytest.approx(mm(XY.reshape(-1, 2)) - y_calc_ref, abs=1e-2) +@pytest.mark.fast @pytest.mark.parametrize( - "fit_engine", + 'fit_engine', [ None, AvailableMinimizers.LMFit, @@ -426,7 +429,7 @@ def test_fixed_parameter_does_not_change(fit_engine): try: f.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') result = f.fit(x=x, y=y, weights=weights) @@ -437,6 +440,7 @@ def test_fixed_parameter_does_not_change(fit_engine): assert sp_sin.phase.value != pytest.approx(ref_sin.phase.value, rel=1e-3) +@pytest.mark.fast def test_fitter_new_model_base_integration(): # WHEN ground_truth = StraightLine(slope=2.0, intercept=1.0) @@ -454,13 +458,12 @@ def test_fitter_new_model_base_integration(): # EXPECT assert model.slope.value == pytest.approx(ground_truth.slope.value, rel=1e-3) - assert model.intercept.value == pytest.approx( - ground_truth.intercept.value, rel=1e-3 - ) + assert model.intercept.value == pytest.approx(ground_truth.intercept.value, rel=1e-3) +@pytest.mark.fast @pytest.mark.parametrize( - "fit_engine", + 'fit_engine', [ None, AvailableMinimizers.LMFit, @@ -501,7 +504,7 @@ def run_fit(weights): try: f.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') f.fit(x=x, y=y, weights=weights) return model.offset.value, model.phase.value @@ -511,6 +514,4 @@ def run_fit(weights): # The fit should shift more toward the distorted region # when it has higher weight - assert abs(offset_high - ref_sin.offset.value) > abs( - offset_low - ref_sin.offset.value - ) + assert abs(offset_high - ref_sin.offset.value) > abs(offset_low - ref_sin.offset.value) diff --git a/tests/integration_tests/fitting/test_multi_fitter.py b/tests/integration/fitting/test_multi_fitter.py similarity index 61% rename from tests/integration_tests/fitting/test_multi_fitter.py rename to tests/integration/fitting/test_multi_fitter.py index fb2c7802..1cc5b395 100644 --- a/tests/integration_tests/fitting/test_multi_fitter.py +++ b/tests/integration/fitting/test_multi_fitter.py @@ -1,14 +1,13 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause +import numpy as np import pytest -import numpy as np -from easyscience.fitting.multi_fitter import MultiFitter -from easyscience.fitting.minimizers import FitError from easyscience import ObjBase from easyscience import Parameter +from easyscience.fitting.minimizers import FitError +from easyscience.fitting.multi_fitter import MultiFitter class Line(ObjBase): @@ -16,22 +15,22 @@ class Line(ObjBase): c: Parameter def __init__(self, m_val: float, c_val: float): - m = Parameter("m", m_val) - c = Parameter("c", c_val) - super(Line, self).__init__("line", m=m, c=c) + m = Parameter('m', m_val) + c = Parameter('c', c_val) + super(Line, self).__init__('line', m=m, c=c) def __call__(self, x): return self.m.value * x + self.c.value - + class AbsSin(ObjBase): phase: Parameter offset: Parameter def __init__(self, offset_val: float, phase_val: float): - offset = Parameter("offset", offset_val) - phase = Parameter("phase", phase_val) - super().__init__("sin", offset=offset, phase=phase) + offset = Parameter('offset', offset_val) + phase = Parameter('phase', phase_val) + super().__init__('sin', offset=offset, phase=phase) def __call__(self, x): return np.abs(np.sin(self.phase.value * x + self.offset.value)) @@ -42,28 +41,32 @@ class AbsSin2D(ObjBase): offset: Parameter def __init__(self, offset_val: float, phase_val: float): - offset = Parameter("offset", offset_val) - phase = Parameter("phase", phase_val) - super().__init__("sin2D", offset=offset, phase=phase) + offset = Parameter('offset', offset_val) + phase = Parameter('phase', phase_val) + super().__init__('sin2D', offset=offset, phase=phase) def __call__(self, x): - X = x[:, :, 0] # x is a 2D array + X = x[:, :, 0] # x is a 2D array Y = x[:, :, 1] - return np.abs( - np.sin(self.phase.value * X + self.offset.value) - ) * np.abs(np.sin(self.phase.value * Y + self.offset.value)) + return np.abs(np.sin(self.phase.value * X + self.offset.value)) * np.abs( + np.sin(self.phase.value * Y + self.offset.value) + ) -@pytest.mark.parametrize("fit_engine", [None, "LMFit", "Bumps", "DFO"]) +@pytest.mark.parametrize('fit_engine', [None, 'LMFit', 'Bumps', 'DFO']) def test_multi_fit(fit_engine): ref_sin_1 = AbsSin(0.2, np.pi) sp_sin_1 = AbsSin(0.354, 3.05) ref_sin_2 = AbsSin(np.pi * 0.45, 0.45 * np.pi * 0.5) sp_sin_2 = AbsSin(1, 0.5) - ref_sin_2.offset.make_dependent_on(dependency_expression="ref_sin1", dependency_map={"ref_sin1": ref_sin_1.offset}) + ref_sin_2.offset.make_dependent_on( + dependency_expression='ref_sin1', dependency_map={'ref_sin1': ref_sin_1.offset} + ) - sp_sin_2.offset.make_dependent_on(dependency_expression="sp_sin1", dependency_map={"sp_sin1": sp_sin_1.offset}) + sp_sin_2.offset.make_dependent_on( + dependency_expression='sp_sin1', dependency_map={'sp_sin1': sp_sin_1.offset} + ) x1 = np.linspace(0, 5, 200) y1 = ref_sin_1(x1) @@ -80,7 +83,7 @@ def test_multi_fit(fit_engine): try: f.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') results = f.fit(x=[x1, x2], y=[y1, y2], weights=[weights, weights]) X = [x1, x2] @@ -91,35 +94,38 @@ def test_multi_fit(fit_engine): assert result.n_pars == len(sp_sin_1.get_fit_parameters()) + len( sp_sin_2.get_fit_parameters() ) - assert result.chi2 == pytest.approx( - 0, abs=1.5e-3 * (len(result.x) - result.n_pars) - ) + assert result.chi2 == pytest.approx(0, abs=1.5e-3 * (len(result.x) - result.n_pars)) assert result.reduced_chi == pytest.approx(0, abs=1.5e-3) assert result.success assert np.all(result.x == X[idx]) assert np.all(result.y_obs == Y[idx]) assert result.y_calc == pytest.approx(F_ref[idx](X[idx]), abs=1e-2) - assert result.residual == pytest.approx( - F_real[idx](X[idx]) - F_ref[idx](X[idx]), abs=1e-2 - ) + assert result.residual == pytest.approx(F_real[idx](X[idx]) - F_ref[idx](X[idx]), abs=1e-2) -@pytest.mark.parametrize("fit_engine", [None, "LMFit", "Bumps", "DFO"]) +@pytest.mark.parametrize('fit_engine', [None, 'LMFit', 'Bumps', 'DFO']) def test_multi_fit2(fit_engine): ref_sin_1 = AbsSin(0.2, np.pi) sp_sin_1 = AbsSin(0.354, 3.05) ref_sin_2 = AbsSin(np.pi * 0.45, 0.45 * np.pi * 0.5) - sp_sin_2 = AbsSin(1, 0.5)# ref_sin_1_obj = genObjs[0] + sp_sin_2 = AbsSin(1, 0.5) # ref_sin_1_obj = genObjs[0] ref_line_obj = Line(1, 4.6) - ref_sin_2.offset.make_dependent_on(dependency_expression="ref_sin1", dependency_map={"ref_sin1": ref_sin_1.offset}) - ref_line_obj.m.make_dependent_on(dependency_expression="ref_sin1", dependency_map={"ref_sin1": ref_sin_1.offset}) + ref_sin_2.offset.make_dependent_on( + dependency_expression='ref_sin1', dependency_map={'ref_sin1': ref_sin_1.offset} + ) + ref_line_obj.m.make_dependent_on( + dependency_expression='ref_sin1', dependency_map={'ref_sin1': ref_sin_1.offset} + ) sp_line = Line(0.43, 6.1) - sp_sin_2.offset.make_dependent_on(dependency_expression="sp_sin1", dependency_map={"sp_sin1": sp_sin_1.offset}) - sp_line.m.make_dependent_on(dependency_expression="sp_sin1", dependency_map={"sp_sin1": sp_sin_1.offset}) - + sp_sin_2.offset.make_dependent_on( + dependency_expression='sp_sin1', dependency_map={'sp_sin1': sp_sin_1.offset} + ) + sp_line.m.make_dependent_on( + dependency_expression='sp_sin1', dependency_map={'sp_sin1': sp_sin_1.offset} + ) x1 = np.linspace(0, 5, 200) y1 = ref_sin_1(x1) @@ -139,7 +145,7 @@ def test_multi_fit2(fit_engine): try: f.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') results = f.fit(x=[x1, x2, x3], y=[y1, y2, y3], weights=[weights, weights, weights]) X = [x1, x2, x3] @@ -153,33 +159,31 @@ def test_multi_fit2(fit_engine): assert result.n_pars == len(sp_sin_1.get_fit_parameters()) + len( sp_sin_2.get_fit_parameters() ) + len(sp_line.get_fit_parameters()) - assert result.chi2 == pytest.approx( - 0, abs=1.5e-3 * (len(result.x) - result.n_pars) - ) + assert result.chi2 == pytest.approx(0, abs=1.5e-3 * (len(result.x) - result.n_pars)) assert result.reduced_chi == pytest.approx(0, abs=1.5e-3) assert result.success assert np.all(result.x == X[idx]) assert np.all(result.y_obs == Y[idx]) assert result.y_calc == pytest.approx(F_real[idx](X[idx]), abs=1e-2) - assert result.residual == pytest.approx( - F_ref[idx](X[idx]) - F_real[idx](X[idx]), abs=1e-2 - ) + assert result.residual == pytest.approx(F_ref[idx](X[idx]) - F_real[idx](X[idx]), abs=1e-2) -@pytest.mark.parametrize("fit_engine", [None, "LMFit", "Bumps", "DFO"]) +@pytest.mark.parametrize('fit_engine', [None, 'LMFit', 'Bumps', 'DFO']) def test_multi_fit_1D_2D(fit_engine): # Generate fit and reference objects ref_sin1D = AbsSin(0.2, np.pi) sp_sin1D = AbsSin(0.354, 3.05) ref_sin2D = AbsSin2D(0.3, 1.6) - sp_sin2D = AbsSin2D( - 0.1, 1.75 - ) # The fit is VERY sensitive to the initial values :-( + sp_sin2D = AbsSin2D(0.1, 1.75) # The fit is VERY sensitive to the initial values :-( # Link the parameters - ref_sin2D.offset.make_dependent_on(dependency_expression="ref_sin1", dependency_map={"ref_sin1": ref_sin1D.offset}) - sp_sin2D.offset.make_dependent_on(dependency_expression="sp_sin1", dependency_map={"sp_sin1": sp_sin1D.offset}) + ref_sin2D.offset.make_dependent_on( + dependency_expression='ref_sin1', dependency_map={'ref_sin1': ref_sin1D.offset} + ) + sp_sin2D.offset.make_dependent_on( + dependency_expression='sp_sin1', dependency_map={'sp_sin1': sp_sin1D.offset} + ) # Generate data x1D = np.linspace(0.2, 3.8, 400) @@ -197,7 +201,7 @@ def test_multi_fit_1D_2D(fit_engine): try: ff.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') sp_sin1D.offset.fixed = False sp_sin1D.phase.fixed = False @@ -208,12 +212,14 @@ def test_multi_fit_1D_2D(fit_engine): try: f.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') try: - results = f.fit(x=[x1D, x2D], y=[y1D, y2D], weights=[weights1D, weights2D], vectorized=True) + results = f.fit( + x=[x1D, x2D], y=[y1D, y2D], weights=[weights1D, weights2D], vectorized=True + ) except FitError as e: - if "Unable to allocate" in str(e): - pytest.skip(msg="MemoryError - Matrix too large") + if 'Unable to allocate' in str(e): + pytest.skip(msg='MemoryError - Matrix too large') else: raise e @@ -225,10 +231,10 @@ def test_multi_fit_1D_2D(fit_engine): assert result.n_pars == len(sp_sin1D.get_fit_parameters()) + len( sp_sin2D.get_fit_parameters() ) - if fit_engine != "DFO": # DFO apparently does not fit well with even weights. Can't be bothered to fix - assert result.chi2 == pytest.approx( - 0, abs=1.5e-3 * (len(result.x) - result.n_pars) - ) + if ( + fit_engine != 'DFO' + ): # DFO apparently does not fit well with even weights. Can't be bothered to fix + assert result.chi2 == pytest.approx(0, abs=1.5e-3 * (len(result.x) - result.n_pars)) assert result.reduced_chi == pytest.approx(0, abs=1.5e-3) assert result.y_calc == pytest.approx(F_ref[idx](X[idx]), abs=1e-2) assert result.residual == pytest.approx( @@ -237,5 +243,3 @@ def test_multi_fit_1D_2D(fit_engine): assert result.success assert np.all(result.x == X[idx]) assert np.all(result.y_obs == Y[idx]) - - diff --git a/tests/integration_tests/fitting/__init__.py b/tests/integration_tests/fitting/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/package_test.py b/tests/package_test.py deleted file mode 100644 index 1e54c8ce..00000000 --- a/tests/package_test.py +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright (c) 2025 Easyscience contributors (https://github.com/EasyScience) -import easyscience as pkg - - -def test_has_version(): - assert hasattr(pkg, '__version__') # noqa S101 diff --git a/tests/unit/base_classes/__init__.py b/tests/unit/base_classes/__init__.py new file mode 100644 index 00000000..b1990ec8 --- /dev/null +++ b/tests/unit/base_classes/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + diff --git a/tests/unit_tests/base_classes/test_collection_base.py b/tests/unit/base_classes/test_collection_base.py similarity index 57% rename from tests/unit_tests/base_classes/test_collection_base.py rename to tests/unit/base_classes/test_collection_base.py index cbd91933..732c3acf 100644 --- a/tests/unit_tests/base_classes/test_collection_base.py +++ b/tests/unit/base_classes/test_collection_base.py @@ -1,35 +1,33 @@ - -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause import pytest import easyscience -from easyscience.base_classes import CollectionBase -from easyscience import ObjBase from easyscience import DescriptorNumber +from easyscience import ObjBase from easyscience import Parameter from easyscience import global_object +from easyscience.base_classes import CollectionBase test_dict = { - "@module": "easyscience.base_classes", - "@class": "CollectionBase", - "@version": easyscience.__version__, - "name": "testing", - "data": [ + '@module': 'easyscience.base_classes', + '@class': 'CollectionBase', + '@version': easyscience.__version__, + 'name': 'testing', + 'data': [ { - "@module": DescriptorNumber.__module__, - "@class": DescriptorNumber.__name__, - "@version": easyscience.__version__, - "name": "par1", - "value": 1.0, - "unit": "dimensionless", - "variance": None, - "unique_name": "CollectionBase_0", - "description": "", - "url": "", - "display_name": "par1", + '@module': DescriptorNumber.__module__, + '@class': DescriptorNumber.__name__, + '@version': easyscience.__version__, + 'name': 'par1', + 'value': 1.0, + 'unit': 'dimensionless', + 'variance': None, + 'unique_name': 'CollectionBase_0', + 'description': '', + 'url': '', + 'display_name': 'par1', } ], } @@ -45,20 +43,20 @@ class Alpha(CollectionBase): @pytest.fixture def setup_pars(): d = { - "name": "test", - "par1": Parameter("p1", 0.1, fixed=True), - "des1": DescriptorNumber("d1", 0.1), - "par2": Parameter("p2", 0.1), - "des2": DescriptorNumber("d2", 0.1), - "par3": Parameter("p3", 0.1), + 'name': 'test', + 'par1': Parameter('p1', 0.1, fixed=True), + 'des1': DescriptorNumber('d1', 0.1), + 'par2': Parameter('p2', 0.1), + 'des2': DescriptorNumber('d2', 0.1), + 'par3': Parameter('p3', 0.1), } return d -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_from_base(cls, setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] coll = cls(name, **setup_pars) assert coll.name == name @@ -70,14 +68,14 @@ def test_CollectionBase_from_base(cls, setup_pars): assert item.value == setup_pars[key].value -@pytest.mark.parametrize("cls", class_constructors) -@pytest.mark.parametrize("value", range(1, 11)) +@pytest.mark.parametrize('cls', class_constructors) +@pytest.mark.parametrize('value', range(1, 11)) def test_CollectionBase_from_ObjBase(cls, setup_pars: dict, value: int): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] objs = {} - prefix = "obj" + prefix = 'obj' for idx in range(value): objs[prefix + str(idx)] = ObjBase(prefix + str(idx), **setup_pars) @@ -94,34 +92,34 @@ def test_CollectionBase_from_ObjBase(cls, setup_pars: dict, value: int): idx += 1 -@pytest.mark.parametrize("cls", class_constructors) -@pytest.mark.parametrize("value", ("abc", False, (), [])) +@pytest.mark.parametrize('cls', class_constructors) +@pytest.mark.parametrize('value', ('abc', False, (), [])) def test_CollectionBase_create_fail(cls, setup_pars, value): - name = setup_pars["name"] - del setup_pars["name"] - setup_pars["to_fail"] = value + name = setup_pars['name'] + del setup_pars['name'] + setup_pars['to_fail'] = value with pytest.raises(AttributeError): coll = cls(name, **setup_pars) -@pytest.mark.parametrize("cls", class_constructors) -@pytest.mark.parametrize("key", ("user_data", "_kwargs", "interface")) +@pytest.mark.parametrize('cls', class_constructors) +@pytest.mark.parametrize('key', ('user_data', '_kwargs', 'interface')) def test_CollectionBase_create_fail2(cls, setup_pars, key): - name = setup_pars["name"] - del setup_pars["name"] - setup_pars[key] = DescriptorNumber("fail_name", 0) + name = setup_pars['name'] + del setup_pars['name'] + setup_pars[key] = DescriptorNumber('fail_name', 0) with pytest.raises(AttributeError): coll = cls(name, **setup_pars) -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_append_base(cls, setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] - new_item_name = "boo" + new_item_name = 'boo' new_item_value = 100 new_item = Parameter(new_item_name, new_item_value) @@ -134,22 +132,22 @@ def test_CollectionBase_append_base(cls, setup_pars): assert coll[-1].value == new_item_value -@pytest.mark.parametrize("cls", class_constructors) -@pytest.mark.parametrize("value", ("abc", False, (), [])) +@pytest.mark.parametrize('cls', class_constructors) +@pytest.mark.parametrize('value', ('abc', False, (), [])) def test_CollectionBase_append_fail(cls, setup_pars, value): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] coll = cls(name, **setup_pars) with pytest.raises(AttributeError): coll.append(value) -@pytest.mark.parametrize("cls", class_constructors) -@pytest.mark.parametrize("value", (0, 1, 3, "par1", "des1")) +@pytest.mark.parametrize('cls', class_constructors) +@pytest.mark.parametrize('value', (0, 1, 3, 'par1', 'des1')) def test_CollectionBase_getItem(cls, setup_pars, value): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] coll = cls(name, **setup_pars) @@ -161,11 +159,11 @@ def test_CollectionBase_getItem(cls, setup_pars, value): assert get_item.name == setup_pars[key].name -@pytest.mark.parametrize("cls", class_constructors) -@pytest.mark.parametrize("value", (False, [], (), 100, 100.4)) +@pytest.mark.parametrize('cls', class_constructors) +@pytest.mark.parametrize('value', (False, [], (), 100, 100.4)) def test_CollectionBase_getItem_type_fail(cls, setup_pars, value): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] coll = cls(name, **setup_pars) @@ -173,10 +171,10 @@ def test_CollectionBase_getItem_type_fail(cls, setup_pars, value): get_item = coll[value] -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_getItem_slice(cls, setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] coll = cls(name, **setup_pars) @@ -184,11 +182,11 @@ def test_CollectionBase_getItem_slice(cls, setup_pars): assert len(get_item) == 2 -@pytest.mark.parametrize("cls", class_constructors) -@pytest.mark.parametrize("value", (0, 1, 3)) +@pytest.mark.parametrize('cls', class_constructors) +@pytest.mark.parametrize('value', (0, 1, 3)) def test_CollectionBase_setItem(cls, setup_pars, value): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] coll = cls(name, **setup_pars) n_coll = len(coll) @@ -203,11 +201,11 @@ def test_CollectionBase_setItem(cls, setup_pars, value): assert coll[value].value == new_item_value -@pytest.mark.parametrize("cls", class_constructors) -@pytest.mark.parametrize("value", ("abc", (), [])) +@pytest.mark.parametrize('cls', class_constructors) +@pytest.mark.parametrize('value', ('abc', (), [])) def test_CollectionBase_setItem_fail(cls, setup_pars, value): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] coll = cls(name, **setup_pars) @@ -216,11 +214,11 @@ def test_CollectionBase_setItem_fail(cls, setup_pars, value): coll[idx] = value -@pytest.mark.parametrize("cls", class_constructors) -@pytest.mark.parametrize("value", (0, 1, 3)) +@pytest.mark.parametrize('cls', class_constructors) +@pytest.mark.parametrize('value', (0, 1, 3)) def test_CollectionBase_delItem(cls, setup_pars, value): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] coll = cls(name, **setup_pars) n_coll = len(coll) @@ -235,11 +233,11 @@ def test_CollectionBase_delItem(cls, setup_pars, value): assert name_coll_idx not in [col.name for col in coll] -@pytest.mark.parametrize("cls", class_constructors) -@pytest.mark.parametrize("value", (0, 1, 3)) +@pytest.mark.parametrize('cls', class_constructors) +@pytest.mark.parametrize('value', (0, 1, 3)) def test_CollectionBase_len(cls, setup_pars, value): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] keys = list(setup_pars.keys()) keys = keys[0 : (value + 1)] @@ -248,100 +246,100 @@ def test_CollectionBase_len(cls, setup_pars, value): assert len(coll) == (value + 1) -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_get_parameters(cls, setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = cls(name, **setup_pars) pars = obj.get_parameters() assert len(pars) == 3 -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_get_parameters_nested(cls, setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = ObjBase(name, **setup_pars) - name2 = name + "_2" + name2 = name + '_2' obj2 = cls(name2, obj=obj, **setup_pars) pars = obj2.get_parameters() assert len(pars) == 6 -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_get_fit_parameters(cls, setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = cls(name, **setup_pars) pars = obj.get_fit_parameters() assert len(pars) == 2 -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_get_fit_parameters_nested(cls, setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = ObjBase(name, **setup_pars) - name2 = name + "_2" + name2 = name + '_2' obj2 = cls(name2, obj=obj, **setup_pars) pars = obj2.get_fit_parameters() assert len(pars) == 4 -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_dir(cls): - name = "testing" - kwargs = {"p1": DescriptorNumber("par1", 1)} + name = 'testing' + kwargs = {'p1': DescriptorNumber('par1', 1)} obj = cls(name, **kwargs) d = set(dir(obj)) expected = { - "user_data", - "reverse", - "constraints", - "get_fit_parameters", - "append", - "unique_name", - "index", - "as_dict", - "clear", - "extend", - "encode", - "remove", - "interface", - "from_dict", - "name", - "switch_interface", - "get_parameters", - "insert", - "data", - "pop", - "count", - "generate_bindings", - "decode", - "sort", + 'user_data', + 'reverse', + 'constraints', + 'get_fit_parameters', + 'append', + 'unique_name', + 'index', + 'as_dict', + 'clear', + 'extend', + 'encode', + 'remove', + 'interface', + 'from_dict', + 'name', + 'switch_interface', + 'get_parameters', + 'insert', + 'data', + 'pop', + 'count', + 'generate_bindings', + 'decode', + 'sort', } assert not d.difference(expected) -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_as_dict(cls): - name = "testing" - kwargs = {"p1": DescriptorNumber("par1", 1)} + name = 'testing' + kwargs = {'p1': DescriptorNumber('par1', 1)} obj = cls(name, **kwargs) d = obj.as_dict() def check_dict(dict_1: dict, dict_2: dict): keys_1 = list(dict_1.keys()) keys_2 = list(dict_2.keys()) - if "unique_name" in keys_1: - del keys_1[keys_1.index("unique_name")] - if "unique_name" in keys_2: - del keys_2[keys_2.index("unique_name")] + if 'unique_name' in keys_1: + del keys_1[keys_1.index('unique_name')] + if 'unique_name' in keys_2: + del keys_2[keys_2.index('unique_name')] assert not set(keys_1).difference(set(keys_2)) @@ -365,18 +363,18 @@ def testit(item1, item2): keys_2.sort() for k1, k2 in zip(keys_1, keys_2): - if k1[0] == "@": + if k1[0] == '@': continue testit(dict_1[k1], dict_2[k2]) check_dict(d, test_dict) -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_from_dict(cls): - global_object.map._clear() #TODO: figure out why this test fails without this line - name = "testing" - kwargs = {"p1": DescriptorNumber("par1", 1)} + global_object.map._clear() # TODO: figure out why this test fails without this line + name = 'testing' + kwargs = {'p1': DescriptorNumber('par1', 1)} expected = cls.from_dict(test_dict) ref = cls(name, **kwargs) @@ -387,23 +385,23 @@ def test_CollectionBase_from_dict(cls): assert item1.value == item2.value -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_repr(cls): - name = "test" - p1 = Parameter("p1", 1) + name = 'test' + p1 = Parameter('p1', 1) obj = cls(name, p1) test_str = str(obj) - ref_str = f"{cls.__name__} `{name}` of length 1" + ref_str = f'{cls.__name__} `{name}` of length 1' assert test_str == ref_str -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_iterator(cls): - name = "test" - p1 = Parameter("p1", 1) - p2 = Parameter("p2", 2) - p3 = Parameter("p3", 3) - p4 = Parameter("p4", 4) + name = 'test' + p1 = Parameter('p1', 1) + p2 = Parameter('p2', 2) + p3 = Parameter('p3', 3) + p4 = Parameter('p4', 4) l_object = [p1, p2, p3, p4] @@ -413,14 +411,14 @@ def test_CollectionBase_iterator(cls): assert item == l_object[index] -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_iterator_dict(cls): - global_object.map._clear() #TODO: figure out why this test fails without this line - name = "test" - p1 = Parameter("p1", 1) - p2 = Parameter("p2", 2) - p3 = Parameter("p3", 3) - p4 = Parameter("p4", 4) + global_object.map._clear() # TODO: figure out why this test fails without this line + name = 'test' + p1 = Parameter('p1', 1) + p2 = Parameter('p2', 2) + p3 = Parameter('p3', 3) + p4 = Parameter('p4', 4) l_object = [p1, p2, p3, p4] @@ -433,14 +431,14 @@ def test_CollectionBase_iterator_dict(cls): assert item.value == l_object[index].value -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_sameName(cls): - global_object.map._clear() #TODO: figure out why this test fails without this line - name = "test" - p1 = Parameter("p1", 1) - p2 = Parameter("p1", 2) - p3 = Parameter("p3", 3) - p4 = Parameter("p4", 4) + global_object.map._clear() # TODO: figure out why this test fails without this line + name = 'test' + p1 = Parameter('p1', 1) + p2 = Parameter('p1', 2) + p3 = Parameter('p3', 3) + p4 = Parameter('p4', 4) l_object = [p1, p2, p3, p4] obj = cls(name, *l_object) @@ -448,19 +446,19 @@ def test_CollectionBase_sameName(cls): for index, item in enumerate(obj): assert item == l_object[index] - obj12 = obj["p1"] + obj12 = obj['p1'] assert len(obj12) == 2 for index, item in enumerate(obj12): assert item == l_object[index] -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_set_index(cls): - name = "test" - p1 = Parameter("p1", 1) - p2 = Parameter("p1", 2) - p3 = Parameter("p3", 3) - p4 = Parameter("p4", 4) + name = 'test' + p1 = Parameter('p1', 1) + p2 = Parameter('p1', 2) + p3 = Parameter('p3', 3) + p4 = Parameter('p4', 4) l_object = [p1, p2, p3] obj = cls(name, *l_object) @@ -476,15 +474,15 @@ def test_CollectionBase_set_index(cls): assert p2.unique_name not in edges -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_set_index_based(cls): - name = "test" - p1 = Parameter("p1", 1) - p2 = Parameter("p2", 2) - p3 = Parameter("p3", 3) - p4 = Parameter("p4", 4) - p5 = Parameter("p5", 5) - d = cls("testing", p1, p2) + name = 'test' + p1 = Parameter('p1', 1) + p2 = Parameter('p2', 2) + p3 = Parameter('p3', 3) + p4 = Parameter('p4', 4) + p5 = Parameter('p5', 5) + d = cls('testing', p1, p2) l_object = [p3, p4, p5] obj = cls(name, *l_object) @@ -500,24 +498,24 @@ def test_CollectionBase_set_index_based(cls): assert p4.unique_name not in edges -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_sort(cls): - name = "test" + name = 'test' v = [1, 4, 3, 2, 5] expected = [1, 2, 3, 4, 5] - d = cls(name, *[Parameter(f"p{i}", v[i]) for i in range(len(v))]) + d = cls(name, *[Parameter(f'p{i}', v[i]) for i in range(len(v))]) d.sort(lambda x: x.value) for i, item in enumerate(d): assert item.value == expected[i] -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBase_sort_reverse(cls): - name = "test" + name = 'test' v = [1, 4, 3, 2, 5] expected = [1, 2, 3, 4, 5] expected.reverse() - d = cls(name, *[Parameter(f"p{i}", v[i]) for i in range(len(v))]) + d = cls(name, *[Parameter(f'p{i}', v[i]) for i in range(len(v))]) d.sort(lambda x: x.value, reverse=True) for i, item in enumerate(d): assert item.value == expected[i] @@ -527,18 +525,18 @@ class Beta(ObjBase): pass -@pytest.mark.parametrize("cls", class_constructors) +@pytest.mark.parametrize('cls', class_constructors) def test_CollectionBaseGraph(cls): from easyscience import global_object G = global_object.map - name = "test" + name = 'test' v = [1, 2] - p = [Parameter(f"p{i}", v[i]) for i in range(len(v))] + p = [Parameter(f'p{i}', v[i]) for i in range(len(v))] p_id = [_p.unique_name for _p in p] bb = cls(name, *p) bb_id = bb.unique_name - b = Beta("b", bb=bb) + b = Beta('b', bb=bb) b_id = b.unique_name for _id in p_id: assert _id in G.get_edges(bb) diff --git a/tests/unit_tests/base_classes/test_easy_list.py b/tests/unit/base_classes/test_easy_list.py similarity index 98% rename from tests/unit_tests/base_classes/test_easy_list.py rename to tests/unit/base_classes/test_easy_list.py index 18e5989c..32f6a60b 100644 --- a/tests/unit_tests/base_classes/test_easy_list.py +++ b/tests/unit/base_classes/test_easy_list.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause import warnings @@ -17,12 +16,14 @@ class Alpha(NewBase): def __init__(self, unique_name=None, display_name=None): super().__init__(unique_name=unique_name, display_name=display_name) + class Beta(NewBase): """Another concrete subclass of NewBase for testing.""" def __init__(self, unique_name=None, display_name=None): super().__init__(unique_name=unique_name, display_name=display_name) + class TestEasyList: @pytest.fixture(autouse=True) def clear(self): @@ -208,7 +209,10 @@ def test_setitem_slice_length_mismatch_raises(self): a2 = Alpha(unique_name='a2') a3 = Alpha(unique_name='a3') el = EasyList(a1, a2, protected_types=Alpha) - with pytest.raises(ValueError, match='Length of new values must match the length of the slice being replaced'): + with pytest.raises( + ValueError, + match='Length of new values must match the length of the slice being replaced', + ): el[0:2] = [a3] # Only one item provided for a slice of length 2 def test_setitem_invalid_index_type(self): diff --git a/tests/unit_tests/base_classes/test_model_base.py b/tests/unit/base_classes/test_model_base.py similarity index 62% rename from tests/unit_tests/base_classes/test_model_base.py rename to tests/unit/base_classes/test_model_base.py index a6d85768..e91c20a9 100644 --- a/tests/unit_tests/base_classes/test_model_base.py +++ b/tests/unit/base_classes/test_model_base.py @@ -1,31 +1,33 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause + +from unittest.mock import MagicMock import pytest + +from easyscience import DescriptorNumber +from easyscience import Parameter from easyscience import global_object from easyscience.base_classes import ModelBase -from easyscience import Parameter -from easyscience import DescriptorNumber -from easyscience.variable import DescriptorStr -from unittest.mock import MagicMock from easyscience.io import SerializerBase -import numpy as np +from easyscience.variable import DescriptorStr + class MockModelComponent(ModelBase): """ A simple mock model component with some parameters and descriptors. """ + def __init__(self, display_name=None, unique_name=None, temperature=0, room_temperature=22): super().__init__(display_name=display_name, unique_name=unique_name) - self._temperature = Parameter(name="temperature", value=temperature) - self._room_temperature = DescriptorNumber(name="room_temperature", value=room_temperature) - self._status = DescriptorStr(name="status", value="OK") + self._temperature = Parameter(name='temperature', value=temperature) + self._room_temperature = DescriptorNumber(name='room_temperature', value=room_temperature) + self._status = DescriptorStr(name='status', value='OK') @property def temperature(self): return self._temperature - + @temperature.setter def temperature(self, value): self._temperature.value = value @@ -33,7 +35,7 @@ def temperature(self, value): @property def room_temperature(self): return self._room_temperature - + @room_temperature.setter def room_temperature(self, value): self._room_temperature.value = value @@ -41,19 +43,21 @@ def room_temperature(self, value): @property def status(self): return self._status - + @status.setter def status(self, value): self._status.value = value + class MockModelFull(ModelBase): """ A mock model that contains another model as a component. To test building nested models using the ModelBase class. """ - def __init__(self, component = None, display_name=None, unique_name=None, pressure=0, area=1): + + def __init__(self, component=None, display_name=None, unique_name=None, pressure=0, area=1): super().__init__(display_name=display_name, unique_name=unique_name) - self._pressure = Parameter(name="pressure", value=pressure) - self._area = Parameter(name="area", value=area) + self._pressure = Parameter(name='pressure', value=pressure) + self._area = Parameter(name='area', value=area) if component is not None: self._component = component else: @@ -62,7 +66,7 @@ def __init__(self, component = None, display_name=None, unique_name=None, pressu @property def pressure(self): return self._pressure - + @pressure.setter def pressure(self, value): self._pressure.value = value @@ -70,22 +74,30 @@ def pressure(self, value): @property def component(self): return self._component - + @property def area(self): return self._area - + @area.setter def area(self, value): self._area.value = value + class TestModelBase: @pytest.fixture def nested_model(self, monkeypatch): model = MockModelFull(pressure=1) - model.pressure.make_dependent_on(dependency_expression="2 * temperature + 5", dependency_map={'temperature': model.component.temperature}) + model.pressure.make_dependent_on( + dependency_expression='2 * temperature + 5', + dependency_map={'temperature': model.component.temperature}, + ) model.area.fixed = True - monkeypatch.setattr(model.component, 'get_all_variables', MagicMock(wraps=model.component.get_all_variables)) + monkeypatch.setattr( + model.component, + 'get_all_variables', + MagicMock(wraps=model.component.get_all_variables), + ) return model @pytest.fixture @@ -95,10 +107,10 @@ def clear(self): def test_init(self): # When Then - model = ModelBase(unique_name="test_model", display_name="Test Model") + model = ModelBase(unique_name='test_model', display_name='Test Model') # Expect - assert model.unique_name == "test_model" - assert model.display_name == "Test Model" + assert model.unique_name == 'test_model' + assert model.display_name == 'Test Model' def test_get_all_variables_flat(self): # When @@ -139,7 +151,9 @@ def test_get_fittable_parameters_nested(self, nested_model): # Expect assert len(fittable_params) == 2 assert any(isinstance(p, Parameter) and p.fixed for p in fittable_params) - assert any(isinstance(p, Parameter) and p.independent and not p.fixed for p in fittable_params) + assert any( + isinstance(p, Parameter) and p.independent and not p.fixed for p in fittable_params + ) assert nested_model.component.get_all_variables.call_count == 1 def test_get_fit_parameters_alias(self, monkeypatch): @@ -162,13 +176,23 @@ def test_get_free_parameters_nested(self, nested_model): def test_from_dict(self, monkeypatch, clear): # When model = MockModelComponent() - obj_dict = model.to_dict() # We only care about deserializing dictorionaries currently created by EasyScience + obj_dict = ( + model.to_dict() + ) # We only care about deserializing dictorionaries currently created by EasyScience obj_dict['@module'] = 'easyscience.base_classes.model_base' - monkeypatch.setattr(SerializerBase, '_import_class', MagicMock(side_effect=lambda module_name, class_name: - MockModelComponent if class_name == 'MockModelComponent' - else Parameter if class_name == 'Parameter' - else DescriptorNumber) - ) + monkeypatch.setattr( + SerializerBase, + '_import_class', + MagicMock( + side_effect=lambda module_name, class_name: ( + MockModelComponent + if class_name == 'MockModelComponent' + else Parameter + if class_name == 'Parameter' + else DescriptorNumber + ) + ), + ) global_object.map._clear() # Then new_model = MockModelComponent.from_dict(obj_dict) @@ -180,20 +204,36 @@ def test_from_dict(self, monkeypatch, clear): assert isinstance(new_model._room_temperature, DescriptorNumber) assert len(global_object.map.vertices()) == 4 assert global_object.map.get_item_by_key('Parameter_0') is new_model._temperature - assert len([param for param in global_object.map.vertices() if param.startswith('Parameter')]) == 1 + assert ( + len([param for param in global_object.map.vertices() if param.startswith('Parameter')]) + == 1 + ) def test_from_dict_nested(self, monkeypatch, clear): # When model = MockModelFull() - model.__class__.__module__ = 'easyscience' # Ensure mock class is seen as easyscience - model.component.__class__.__module__ = 'easyscience' # Ensure nested class is also seen as easyscience - obj_dict = model.to_dict() # We only care about deserializing dictorionaries currently created by EasyScience - monkeypatch.setattr(SerializerBase, '_import_class', MagicMock(side_effect=lambda module_name, class_name: - MockModelFull if class_name == 'MockModelFull' - else MockModelComponent if class_name == 'MockModelComponent' - else Parameter if class_name == 'Parameter' - else DescriptorNumber) - ) + model.__class__.__module__ = 'easyscience' # Ensure mock class is seen as easyscience + model.component.__class__.__module__ = ( + 'easyscience' # Ensure nested class is also seen as easyscience + ) + obj_dict = ( + model.to_dict() + ) # We only care about deserializing dictorionaries currently created by EasyScience + monkeypatch.setattr( + SerializerBase, + '_import_class', + MagicMock( + side_effect=lambda module_name, class_name: ( + MockModelFull + if class_name == 'MockModelFull' + else MockModelComponent + if class_name == 'MockModelComponent' + else Parameter + if class_name == 'Parameter' + else DescriptorNumber + ) + ), + ) global_object.map._clear() # Then new_model = MockModelFull.from_dict(obj_dict) @@ -209,18 +249,27 @@ def test_from_dict_nested(self, monkeypatch, clear): assert isinstance(new_model.component._temperature, Parameter) assert isinstance(new_model.component._room_temperature, DescriptorNumber) assert len(global_object.map.vertices()) == 7 - assert global_object.map.get_item_by_key('Parameter_0') in [new_model._pressure, new_model._area, new_model.component._temperature] - assert len([param for param in global_object.map.vertices() if param.startswith('Parameter')]) == 3 + assert global_object.map.get_item_by_key('Parameter_0') in [ + new_model._pressure, + new_model._area, + new_model.component._temperature, + ] + assert ( + len([param for param in global_object.map.vertices() if param.startswith('Parameter')]) + == 3 + ) def test_from_dict_not_easyscience(self): # When obj_dict = { '@module': 'some.other.module', '@class': 'NotAnEasyScienceObject', - 'some_property': 42 + 'some_property': 42, } # Then / Expect - with pytest.raises(ValueError, match='Input must be a dictionary representing an EasyScience object.'): + with pytest.raises( + ValueError, match='Input must be a dictionary representing an EasyScience object.' + ): MockModelComponent.from_dict(obj_dict) def test_from_dict_wrong_class(self): @@ -228,25 +277,45 @@ def test_from_dict_wrong_class(self): obj_dict = { '@module': 'easyscience.base_classes.model_base', '@class': 'SomeOtherClass', - 'some_property': 42 + 'some_property': 42, } # Then / Expect - with pytest.raises(ValueError, match='Class name in dictionary does not match the expected class: MockModelComponent.'): + with pytest.raises( + ValueError, + match='Class name in dictionary does not match the expected class: MockModelComponent.', + ): MockModelComponent.from_dict(obj_dict) def test_from_dict_parameter_setting_failure(self, monkeypatch, clear): # When model = MockModelComponent() model.temperature.min = -100 - obj_dict = model.to_dict() # We only care about deserializing dictorionaries currently created by EasyScience + obj_dict = ( + model.to_dict() + ) # We only care about deserializing dictorionaries currently created by EasyScience obj_dict['@module'] = 'easyscience.base_classes.model_base' - monkeypatch.setattr(SerializerBase, '_import_class', MagicMock(side_effect=lambda module_name, class_name: - MockModelComponent if class_name == 'MockModelComponent' - else Parameter if class_name == 'Parameter' - else DescriptorNumber) - ) - monkeypatch.setattr(MockModelComponent, 'temperature', property(lambda self: (_ for _ in ()).throw(Exception("Simulated failure")))) + monkeypatch.setattr( + SerializerBase, + '_import_class', + MagicMock( + side_effect=lambda module_name, class_name: ( + MockModelComponent + if class_name == 'MockModelComponent' + else Parameter + if class_name == 'Parameter' + else DescriptorNumber + ) + ), + ) + monkeypatch.setattr( + MockModelComponent, + 'temperature', + property(lambda self: (_ for _ in ()).throw(Exception('Simulated failure'))), + ) global_object.map._clear() # Then Expect - with pytest.raises(SyntaxError, match='Could not set parameter temperature during `from_dict` with full deserialized variable.'): - MockModelComponent.from_dict(obj_dict) \ No newline at end of file + with pytest.raises( + SyntaxError, + match='Could not set parameter temperature during `from_dict` with full deserialized variable.', + ): + MockModelComponent.from_dict(obj_dict) diff --git a/tests/unit_tests/base_classes/test_new_base.py b/tests/unit/base_classes/test_new_base.py similarity index 76% rename from tests/unit_tests/base_classes/test_new_base.py rename to tests/unit/base_classes/test_new_base.py index e9ca79d7..e1562860 100644 --- a/tests/unit_tests/base_classes/test_new_base.py +++ b/tests/unit/base_classes/test_new_base.py @@ -1,13 +1,13 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause import pytest + from easyscience import global_object from easyscience.base_classes import NewBase -class TestNewBase: +class TestNewBase: @pytest.fixture def clear(self): # Clear the global object map before each test @@ -24,12 +24,12 @@ def test_constructor_defaults(self, clear): def test_constructor_with_arguments(self): # When Then - obj = NewBase(unique_name="custom_name", display_name="My Object") + obj = NewBase(unique_name='custom_name', display_name='My Object') # Expect - assert obj._unique_name == "custom_name" + assert obj._unique_name == 'custom_name' assert obj._default_unique_name is False - assert obj._display_name == "My Object" - assert global_object.map.get_item_by_key("custom_name") is obj + assert obj._display_name == 'My Object' + assert global_object.map.get_item_by_key('custom_name') is obj def test_constructor_invalid_unique_name(self): # When Then Expect @@ -54,12 +54,12 @@ def test_unique_name_setter(self, clear): # When obj = NewBase() # Then - obj.unique_name = "new_unique_name" + obj.unique_name = 'new_unique_name' # Expect - assert obj.unique_name == "new_unique_name" + assert obj.unique_name == 'new_unique_name' assert obj._default_unique_name is False - assert global_object.map.get_item_by_key("new_unique_name") is obj - assert global_object.map.get_item_by_key("NewBase_0") is obj + assert global_object.map.get_item_by_key('new_unique_name') is obj + assert global_object.map.get_item_by_key('NewBase_0') is obj def test_unique_name_setter_invalid(self): # When @@ -81,10 +81,10 @@ def test_display_name_setter(self): # When obj = NewBase() # Then - obj.display_name = "Pretty Name" + obj.display_name = 'Pretty Name' # Expect - assert obj.display_name == "Pretty Name" - assert obj._display_name == "Pretty Name" + assert obj.display_name == 'Pretty Name' + assert obj._display_name == 'Pretty Name' def test_display_name_setter_invalid(self): # When @@ -95,13 +95,13 @@ def test_display_name_setter_invalid(self): def test_to_dict_full_params(self): # When - obj = NewBase(unique_name="test_name", display_name="Test Object") + obj = NewBase(unique_name='test_name', display_name='Test Object') # Then obj_dict = obj.to_dict() # Expect assert isinstance(obj_dict, dict) - assert obj_dict['unique_name'] == "test_name" - assert obj_dict['display_name'] == "Test Object" + assert obj_dict['unique_name'] == 'test_name' + assert obj_dict['display_name'] == 'Test Object' assert obj_dict['@module'] == 'easyscience.base_classes.new_base' assert obj_dict['@class'] == 'NewBase' assert '@version' in obj_dict @@ -121,12 +121,12 @@ def test_to_dict_default_params(self): def test_to_dict_with_skip(self): # When - obj = NewBase(unique_name="skip_test", display_name="Skip Test Object") + obj = NewBase(unique_name='skip_test', display_name='Skip Test Object') # Then obj_dict = obj.to_dict(skip=['display_name']) # Expect assert isinstance(obj_dict, dict) - assert obj_dict['unique_name'] == "skip_test" + assert obj_dict['unique_name'] == 'skip_test' assert 'display_name' not in obj_dict assert obj_dict['@module'] == 'easyscience.base_classes.new_base' assert obj_dict['@class'] == 'NewBase' @@ -138,7 +138,7 @@ def test_from_dict(self): '@module': 'easyscience.base_classes.new_base', '@class': 'NewBase', 'unique_name': 'from_dict_name', - 'display_name': 'From Dict Object' + 'display_name': 'From Dict Object', } # Then obj = NewBase.from_dict(obj_dict) @@ -154,10 +154,12 @@ def test_from_dict_not_easyscience(self): '@module': 'some.other.module', '@class': 'NewBase', 'unique_name': 'invalid_from_dict', - 'display_name': 'Invalid From Dict Object' + 'display_name': 'Invalid From Dict Object', } # Then Expect - with pytest.raises(ValueError, match='Input must be a dictionary representing an EasyScience object.'): + with pytest.raises( + ValueError, match='Input must be a dictionary representing an EasyScience object.' + ): NewBase.from_dict(obj_dict) def test_from_dict_wrong_class(self): @@ -166,10 +168,13 @@ def test_from_dict_wrong_class(self): '@module': 'easyscience.base_classes.new_base', '@class': 'SomeOtherClass', 'unique_name': 'wrong_class_name', - 'display_name': 'Wrong Class Object' + 'display_name': 'Wrong Class Object', } # Then Expect - with pytest.raises(ValueError, match='Class name in dictionary does not match the expected class: NewBase.'): + with pytest.raises( + ValueError, + match='Class name in dictionary does not match the expected class: NewBase.', + ): NewBase.from_dict(obj_dict) def test__dir__(self): @@ -189,7 +194,7 @@ def test__dir__(self): def test_copy(self): # When - obj = NewBase(unique_name="original_name", display_name="Original Object") + obj = NewBase(unique_name='original_name', display_name='Original Object') # Then obj_copy = obj.__copy__() # Expect @@ -200,12 +205,13 @@ def test_copy(self): def test_deepcopy(self): # When - obj = NewBase(unique_name="deepcopy_name", display_name="Deep Copy Object") + obj = NewBase(unique_name='deepcopy_name', display_name='Deep Copy Object') # Then import copy + obj_deepcopy = copy.deepcopy(obj) # Expect assert isinstance(obj_deepcopy, NewBase) assert obj_deepcopy.unique_name != obj.unique_name assert obj_deepcopy.display_name == obj.display_name - assert global_object.map.get_item_by_key(obj_deepcopy.unique_name) is obj_deepcopy \ No newline at end of file + assert global_object.map.get_item_by_key(obj_deepcopy.unique_name) is obj_deepcopy diff --git a/tests/unit_tests/base_classes/test_obj_base.py b/tests/unit/base_classes/test_obj_base.py similarity index 59% rename from tests/unit_tests/base_classes/test_obj_base.py rename to tests/unit/base_classes/test_obj_base.py index f004e9af..357aa4f1 100644 --- a/tests/unit_tests/base_classes/test_obj_base.py +++ b/tests/unit/base_classes/test_obj_base.py @@ -1,11 +1,8 @@ - -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause from contextlib import contextmanager from copy import copy - from typing import ClassVar from typing import List from typing import Optional @@ -16,56 +13,54 @@ import pytest import easyscience -from easyscience import ObjBase from easyscience import DescriptorNumber +from easyscience import ObjBase from easyscience import Parameter from easyscience import global_object from easyscience.io import SerializerDict + @pytest.fixture def clear(): global_object.map._clear() + @pytest.fixture def setup_pars(): d = { - "name": "test", - "par1": Parameter("p1", 0.1, fixed=True), - "des1": DescriptorNumber("d1", 0.1), - "par2": Parameter("p2", 0.1), - "des2": DescriptorNumber("d2", 0.1), - "par3": Parameter("p3", 0.1), + 'name': 'test', + 'par1': Parameter('p1', 0.1, fixed=True), + 'des1': DescriptorNumber('d1', 0.1), + 'par2': Parameter('p2', 0.1), + 'des2': DescriptorNumber('d2', 0.1), + 'par3': Parameter('p3', 0.1), } return d @contextmanager -def not_raises( - expected_exception: Union[Type[BaseException], List[Type[BaseException]]] -): +def not_raises(expected_exception: Union[Type[BaseException], List[Type[BaseException]]]): try: yield except expected_exception: raise pytest.fail( - "Did raise exception {0} when it should not.".format( - repr(expected_exception) - ) + 'Did raise exception {0} when it should not.'.format(repr(expected_exception)) ) except Exception as err: - raise pytest.fail("An unexpected exception {0} raised.".format(repr(err))) + raise pytest.fail('An unexpected exception {0} raised.'.format(repr(err))) @pytest.mark.parametrize( - "a, kw", + 'a, kw', [ - ([], ["par1"]), - (["par1"], []), - (["par1"], ["par2"]), - (["par1", "des1"], ["par2", "des2"]), + ([], ['par1']), + (['par1'], []), + (['par1'], ['par2']), + (['par1', 'des1'], ['par2', 'des2']), ], ) def test_ObjBase_create(setup_pars: dict, a: List[str], kw: List[str]): - name = setup_pars["name"] + name = setup_pars['name'] args = [] for key in a: args.append(setup_pars[key]) @@ -81,12 +76,12 @@ def test_ObjBase_create(setup_pars: dict, a: List[str], kw: List[str]): def test_ObjBase_copy(setup_pars: dict): # When - name = setup_pars["name"] + name = setup_pars['name'] args = [] - for key in ["par1", "des1"]: + for key in ['par1', 'des1']: args.append(setup_pars[key]) kwargs = {} - for key in ["par2", "des2"]: + for key in ['par2', 'des2']: kwargs[key] = setup_pars[key] base = ObjBase(name, None, *args, **kwargs) @@ -97,15 +92,15 @@ def test_ObjBase_copy(setup_pars: dict): assert base_copy.name == name assert base_copy.unique_name != base.unique_name - for key in ["par1", "des1"]: + for key in ['par1', 'des1']: item = getattr(base, setup_pars[key].name) assert isinstance(item, setup_pars[key].__class__) def test_ObjBase_get(setup_pars: dict): - name = setup_pars["name"] - explicit_name1 = "par1" - explicit_name2 = "par2" + name = setup_pars['name'] + explicit_name1 = 'par1' + explicit_name2 = 'par2' kwargs = { setup_pars[explicit_name1].name: setup_pars[explicit_name1], setup_pars[explicit_name2].name: setup_pars[explicit_name2], @@ -118,8 +113,8 @@ def test_ObjBase_get(setup_pars: dict): def test_ObjBase_set(setup_pars: dict): - name = setup_pars["name"] - explicit_name1 = "par1" + name = setup_pars['name'] + explicit_name1 = 'par1' kwargs = { setup_pars[explicit_name1].name: setup_pars[explicit_name1], } @@ -131,15 +126,15 @@ def test_ObjBase_set(setup_pars: dict): def test_ObjBase_get_parameters(setup_pars: dict): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = ObjBase(name, **setup_pars) pars = obj.get_fit_parameters() assert isinstance(pars, list) assert len(pars) == 2 par_names = [par.name for par in pars] - assert "p2" in par_names - assert "p3" in par_names + assert 'p2' in par_names + assert 'p3' in par_names def test_ObjBase_fit_objects(setup_pars: dict): @@ -147,83 +142,83 @@ def test_ObjBase_fit_objects(setup_pars: dict): def test_ObjBase_as_dict(clear, setup_pars: dict): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = ObjBase(name, **setup_pars) obtained = obj.as_dict() assert isinstance(obtained, dict) expected = { - "@module": "easyscience.base_classes.obj_base", - "@class": "ObjBase", - "@version": easyscience.__version__, - "name": "test", - "par1": { - "@module": Parameter.__module__, - "@class": Parameter.__name__, - "@version": easyscience.__version__, - "name": "p1", - "value": 0.1, - "variance": 0.0, - "min": -np.inf, - "max": np.inf, - "fixed": True, - "unit": "dimensionless", + '@module': 'easyscience.base_classes.obj_base', + '@class': 'ObjBase', + '@version': easyscience.__version__, + 'name': 'test', + 'par1': { + '@module': Parameter.__module__, + '@class': Parameter.__name__, + '@version': easyscience.__version__, + 'name': 'p1', + 'value': 0.1, + 'variance': 0.0, + 'min': -np.inf, + 'max': np.inf, + 'fixed': True, + 'unit': 'dimensionless', }, - "des1": { - "@module": DescriptorNumber.__module__, - "@class": DescriptorNumber.__name__, - "@module": DescriptorNumber.__module__, - "@class": DescriptorNumber.__name__, - "@version": easyscience.__version__, - "name": "d1", - "value": 0.1, - "unit": "dimensionless", - "description": "", - "url": "", - "display_name": "d1", + 'des1': { + '@module': DescriptorNumber.__module__, + '@class': DescriptorNumber.__name__, + '@module': DescriptorNumber.__module__, + '@class': DescriptorNumber.__name__, + '@version': easyscience.__version__, + 'name': 'd1', + 'value': 0.1, + 'unit': 'dimensionless', + 'description': '', + 'url': '', + 'display_name': 'd1', }, - "par2": { - "@module": Parameter.__module__, - "@class": Parameter.__name__, - "@version": easyscience.__version__, - "name": "p2", - "value": 0.1, - "variance": 0.0, - "min": -np.inf, - "max": np.inf, - "fixed": False, - "unit": "dimensionless", + 'par2': { + '@module': Parameter.__module__, + '@class': Parameter.__name__, + '@version': easyscience.__version__, + 'name': 'p2', + 'value': 0.1, + 'variance': 0.0, + 'min': -np.inf, + 'max': np.inf, + 'fixed': False, + 'unit': 'dimensionless', }, - "des2": { - "@module": DescriptorNumber.__module__, - "@class": DescriptorNumber.__name__, - "@module": DescriptorNumber.__module__, - "@class": DescriptorNumber.__name__, - "@version": easyscience.__version__, - "name": "d2", - "value": 0.1, - "unit": "dimensionless", - "description": "", - "url": "", - "display_name": "d2", + 'des2': { + '@module': DescriptorNumber.__module__, + '@class': DescriptorNumber.__name__, + '@module': DescriptorNumber.__module__, + '@class': DescriptorNumber.__name__, + '@version': easyscience.__version__, + 'name': 'd2', + 'value': 0.1, + 'unit': 'dimensionless', + 'description': '', + 'url': '', + 'display_name': 'd2', }, - "par3": { - "@module": Parameter.__module__, - "@class": Parameter.__name__, - "@version": easyscience.__version__, - "name": "p3", - "value": 0.1, - "variance": 0.0, - "min": -np.inf, - "max": np.inf, - "fixed": False, - "unit": "dimensionless", + 'par3': { + '@module': Parameter.__module__, + '@class': Parameter.__name__, + '@version': easyscience.__version__, + 'name': 'p3', + 'value': 0.1, + 'variance': 0.0, + 'min': -np.inf, + 'max': np.inf, + 'fixed': False, + 'unit': 'dimensionless', }, } def check_dict(check, item): if isinstance(check, dict) and isinstance(item, dict): - if "@module" in item.keys(): + if '@module' in item.keys(): with not_raises([ValueError, AttributeError]): global_object.map._clear() this_obj = SerializerDict().decode(item) @@ -240,8 +235,8 @@ def check_dict(check, item): def test_ObjBase_dict_roundtrip(clear, setup_pars: dict): # When - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = ObjBase(name, **setup_pars, unique_name='special_name') obj_dict = obj.as_dict() @@ -256,27 +251,27 @@ def test_ObjBase_dict_roundtrip(clear, setup_pars: dict): def test_ObjBase_dir(setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = ObjBase(name, **setup_pars) expected = [ - "encode", - "decode", - "as_dict", - "des1", - "des2", - "from_dict", - "generate_bindings", - "get_fit_parameters", - "get_parameters", - "interface", - "unique_name", - "name", - "par1", - "par2", - "par3", - "switch_interface", - "user_data", + 'encode', + 'decode', + 'as_dict', + 'des1', + 'des2', + 'from_dict', + 'generate_bindings', + 'get_fit_parameters', + 'get_parameters', + 'interface', + 'unique_name', + 'name', + 'par1', + 'par2', + 'par3', + 'switch_interface', + 'user_data', ] obtained = dir(obj) print(obtained) @@ -287,19 +282,19 @@ def test_ObjBase_dir(setup_pars): def test_ObjBase_get_parameters(setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = ObjBase(name, **setup_pars) pars = obj.get_parameters() assert len(pars) == 3 def test_ObjBase_get_parameters_nested(setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = ObjBase(name, **setup_pars) - name2 = name + "_2" + name2 = name + '_2' obj2 = ObjBase(name2, obj=obj, **setup_pars) pars = obj2.get_parameters() @@ -310,19 +305,19 @@ def test_ObjBase_get_parameters_nested(setup_pars): def test_ObjBase_get_fit_parameters(setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = ObjBase(name, **setup_pars) pars = obj.get_fit_parameters() assert len(pars) == 2 def test_ObjBase_get_fit_parameters_nested(setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = ObjBase(name, **setup_pars) - name2 = name + "_2" + name2 = name + '_2' obj2 = ObjBase(name2, obj=obj, **setup_pars) pars = obj2.get_fit_parameters() @@ -333,12 +328,12 @@ def test_ObjBase_get_fit_parameters_nested(setup_pars): def test_ObjBase__add_component(setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = ObjBase(name, **setup_pars) - p = Parameter("added_par", 1) - new_item_name = "Added" + p = Parameter('added_par', 1) + new_item_name = 'Added' obj._add_component(new_item_name, p) assert hasattr(obj, new_item_name) @@ -347,19 +342,20 @@ def test_ObjBase__add_component(setup_pars): def test_ObjBase_name(setup_pars): - name = setup_pars["name"] - del setup_pars["name"] + name = setup_pars['name'] + del setup_pars['name'] obj = ObjBase(name, **setup_pars) assert obj.name == name + def test_Base_GETSET(): class A(ObjBase): def __init__(self, a: Parameter): - super(A, self).__init__("a", a=a) + super(A, self).__init__('a', a=a) @classmethod def from_pars(cls, a: float): - return cls(a=Parameter("a", a)) + return cls(a=Parameter('a', a)) a_start = 5 a_end = 10 @@ -369,7 +365,7 @@ def from_pars(cls, a: float): assert a.a.value == a_start assert len(graph.get_edges(a)) == 1 - setattr(a, "a", a_end) + setattr(a, 'a', a_end) assert a.a.value == a_end assert len(graph.get_edges(a)) == 1 @@ -377,12 +373,12 @@ def from_pars(cls, a: float): def test_Base_GETSET(): class A(ObjBase): def __init__(self, a: Parameter): - super(A, self).__init__("a", a=a) + super(A, self).__init__('a', a=a) b = 0 @classmethod def from_pars(cls, a: float): - return cls(a=Parameter("a", a)) + return cls(a=Parameter('a', a)) a = A.from_pars(5) b_new = 10 @@ -392,15 +388,14 @@ def from_pars(cls, a: float): def test_Base_GETSET_v2(): class A(ObjBase): - a: ClassVar[Parameter] def __init__(self, a: Parameter): - super(A, self).__init__("a", a=a) + super(A, self).__init__('a', a=a) @classmethod def from_pars(cls, a: float): - return cls(a=Parameter("a", a)) + return cls(a=Parameter('a', a)) a_start = 5 a_end = 10 @@ -410,22 +405,21 @@ def from_pars(cls, a: float): assert a.a.value == a_start assert len(graph.get_edges(a)) == 1 - setattr(a, "a", a_end) + setattr(a, 'a', a_end) assert a.a.value == a_end assert len(graph.get_edges(a)) == 1 def test_Base_GETSET_v3(): class A(ObjBase): - a: ClassVar[Parameter] def __init__(self, a: Parameter): - super(A, self).__init__("a", a=a) + super(A, self).__init__('a', a=a) @classmethod def from_pars(cls, a: float): - return cls(a=Parameter("a", a)) + return cls(a=Parameter('a', a)) a_start = 5 a_end = 10 @@ -434,11 +428,11 @@ def from_pars(cls, a: float): assert a.a.value == a_start assert len(graph.get_edges(a)) == 1 - a_ = Parameter("a", a_end) + a_ = Parameter('a', a_end) assert a.a.unique_name in graph.get_edges(a) a__ = a.a - setattr(a, "a", a_) + setattr(a, 'a', a_) assert a.a.value == a_end assert len(graph.get_edges(a)) == 1 assert a_.unique_name in graph.get_edges(a) @@ -448,7 +442,7 @@ def from_pars(cls, a: float): def test_BaseCreation(): class A(ObjBase): def __init__(self, a: Optional[Union[Parameter, float]] = None): - super(A, self).__init__("A", a=Parameter("a", 1.0)) + super(A, self).__init__('A', a=Parameter('a', 1.0)) if a is not None: self.a = a @@ -456,14 +450,14 @@ def __init__(self, a: Optional[Union[Parameter, float]] = None): assert a.a.value == 1.0 a = A(2.0) assert a.a.value == 2.0 - a = A(Parameter("a", 3.0)) + a = A(Parameter('a', 3.0)) assert a.a.value == 3.0 a.a = 4.0 assert a.a.value == 4.0 class B(ObjBase): def __init__(self, b: Optional[Union[A, Parameter, float]] = None): - super(B, self).__init__("B", b=A()) + super(B, self).__init__('B', b=A()) if b is not None: if isinstance(b, (float, Parameter)): b = A(b) @@ -478,24 +472,27 @@ def __init__(self, b: Optional[Union[A, Parameter, float]] = None): b.b.a = 4.0 assert b.b.a.value == 4.0 + def test_unique_name_generator(clear): # When Then - test_obj = ObjBase(name="test") + test_obj = ObjBase(name='test') # Expect - assert test_obj.unique_name == "ObjBase_0" + assert test_obj.unique_name == 'ObjBase_0' + def test_unique_name_change(clear): # When - test_obj = ObjBase(name="test") + test_obj = ObjBase(name='test') # Then - test_obj.unique_name = "test" + test_obj.unique_name = 'test' # Expect - assert test_obj.unique_name == "test" + assert test_obj.unique_name == 'test' + -@pytest.mark.parametrize("input", [2, 2.0, [2], {2}, None]) +@pytest.mark.parametrize('input', [2, 2.0, [2], {2}, None]) def test_unique_name_change_exception(input): # When - test_obj = ObjBase(name="test") + test_obj = ObjBase(name='test') # Then Expect with pytest.raises(TypeError): - test_obj.unique_name = input \ No newline at end of file + test_obj.unique_name = input diff --git a/tests/unit/fitting/__init__.py b/tests/unit/fitting/__init__.py new file mode 100644 index 00000000..b1990ec8 --- /dev/null +++ b/tests/unit/fitting/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + diff --git a/tests/unit/fitting/calculators/__init__.py b/tests/unit/fitting/calculators/__init__.py new file mode 100644 index 00000000..b1990ec8 --- /dev/null +++ b/tests/unit/fitting/calculators/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + diff --git a/tests/unit_tests/fitting/calculators/test_interface_factory.py b/tests/unit/fitting/calculators/test_interface_factory.py similarity index 74% rename from tests/unit_tests/fitting/calculators/test_interface_factory.py rename to tests/unit/fitting/calculators/test_interface_factory.py index ce7b8542..cab3b30f 100644 --- a/tests/unit_tests/fitting/calculators/test_interface_factory.py +++ b/tests/unit/fitting/calculators/test_interface_factory.py @@ -1,12 +1,13 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause + +from unittest.mock import MagicMock -from unittest.mock import MagicMock, patch import pytest -from easyscience.fitting.calculators.interface_factory import InterfaceFactoryTemplate, ItemContainer from easyscience import global_object +from easyscience.fitting.calculators.interface_factory import InterfaceFactoryTemplate +from easyscience.fitting.calculators.interface_factory import ItemContainer class TestInterfaceFactoryTemplate: @@ -16,64 +17,67 @@ def clear(self): global_object.map._clear() yield global_object.map._clear() - + @pytest.fixture def mock_interface1(self): """Create a mock interface class""" + class MockInterface1: - name = "MockInterface1" - + name = 'MockInterface1' + def __init__(self, *args, **kwargs): self.args = args self.kwargs = kwargs - + def fit_func(self, *args, **kwargs): - return "result1" - + return 'result1' + def create(self, model): return [] - + return MockInterface1 - + @pytest.fixture def mock_interface2(self): """Create a second mock interface class""" + class MockInterface2: def __init__(self, *args, **kwargs): self.args = args self.kwargs = kwargs - + def fit_func(self, *args, **kwargs): - return "result2" - + return 'result2' + def create(self, model): return [] - + return MockInterface2 - + @pytest.fixture def mock_interface_with_custom_name(self): """Create a mock interface with custom name attribute""" + class MockInterfaceCustom: - name = "CustomName" - + name = 'CustomName' + def __init__(self, *args, **kwargs): self.args = args self.kwargs = kwargs - + def fit_func(self, *args, **kwargs): - return "custom_result" - + return 'custom_result' + def create(self, model): return [] - + return MockInterfaceCustom - + @pytest.fixture def factory_single_interface(self, clear, mock_interface1): """Create factory with single interface""" return InterfaceFactoryTemplate([mock_interface1]) - + @pytest.fixture def factory_multiple_interfaces(self, clear, mock_interface1, mock_interface2): """Create factory with multiple interfaces""" @@ -83,7 +87,7 @@ def test_init_with_single_interface_default_selection(self, clear, mock_interfac """Test initialization with single interface uses first as default""" # When factory = InterfaceFactoryTemplate([mock_interface1]) - + # Then assert factory._interfaces == [mock_interface1] assert factory._current_interface == mock_interface1 @@ -99,8 +103,10 @@ def test_init_with_empty_interface_list_raises_error(self, clear): def test_init_with_specific_interface_name(self, clear, mock_interface1, mock_interface2): """Test initialization with specific interface name""" # When - factory = InterfaceFactoryTemplate([mock_interface1, mock_interface2], interface_name="MockInterface2") - + factory = InterfaceFactoryTemplate( + [mock_interface1, mock_interface2], interface_name='MockInterface2' + ) + # Then assert factory._current_interface == mock_interface2 assert isinstance(factory(), mock_interface2) @@ -108,27 +114,29 @@ def test_init_with_specific_interface_name(self, clear, mock_interface1, mock_in def test_init_passes_args_and_kwargs_to_interface(self, clear, mock_interface1): """Test that args and kwargs are passed to interface constructor""" # When - factory = InterfaceFactoryTemplate([mock_interface1], "arg1", "arg2", kwarg1="value1") - + factory = InterfaceFactoryTemplate([mock_interface1], 'arg1', 'arg2', kwarg1='value1') + # Then interface_obj = factory() - assert interface_obj.args == ("arg1", "arg2") - assert interface_obj.kwargs == {"kwarg1": "value1"} + assert interface_obj.args == ('arg1', 'arg2') + assert interface_obj.kwargs == {'kwarg1': 'value1'} def test_create_with_interface_name(self, factory_multiple_interfaces, mock_interface2): """Test create method with specific interface name""" # When - factory_multiple_interfaces.create(interface_name="MockInterface2") - + factory_multiple_interfaces.create(interface_name='MockInterface2') + # Then assert factory_multiple_interfaces._current_interface == mock_interface2 assert isinstance(factory_multiple_interfaces(), mock_interface2) - def test_create_without_interface_name_uses_first(self, factory_multiple_interfaces, mock_interface1): + def test_create_without_interface_name_uses_first( + self, factory_multiple_interfaces, mock_interface1 + ): """Test create method without interface name uses first interface""" # When factory_multiple_interfaces.create() - + # Then assert factory_multiple_interfaces._current_interface == mock_interface1 @@ -136,10 +144,10 @@ def test_available_interfaces_property(self, factory_multiple_interfaces): """Test available_interfaces property returns correct names""" # When interfaces = factory_multiple_interfaces.available_interfaces - + # Then - assert "MockInterface1" in interfaces - assert "MockInterface2" in interfaces + assert 'MockInterface1' in interfaces + assert 'MockInterface2' in interfaces assert len(interfaces) == 2 def test_current_interface_property(self, factory_single_interface, mock_interface1): @@ -150,13 +158,13 @@ def test_current_interface_property(self, factory_single_interface, mock_interfa def test_current_interface_name_property(self, factory_single_interface): """Test current_interface_name property returns correct name""" # When/Then - assert factory_single_interface.current_interface_name == "MockInterface1" + assert factory_single_interface.current_interface_name == 'MockInterface1' def test_switch_to_valid_interface(self, factory_multiple_interfaces, mock_interface2): """Test switching to a valid interface""" # When - factory_multiple_interfaces.switch("MockInterface2") - + factory_multiple_interfaces.switch('MockInterface2') + # Then assert factory_multiple_interfaces._current_interface == mock_interface2 assert isinstance(factory_multiple_interfaces(), mock_interface2) @@ -164,20 +172,22 @@ def test_switch_to_valid_interface(self, factory_multiple_interfaces, mock_inter def test_switch_to_invalid_interface_raises_error(self, factory_single_interface): """Test switching to invalid interface raises AttributeError""" # When/Then - with pytest.raises(AttributeError, match="The user supplied interface is not valid"): - factory_single_interface.switch("NonExistentInterface") + with pytest.raises(AttributeError, match='The user supplied interface is not valid'): + factory_single_interface.switch('NonExistentInterface') - def test_switch_with_fitter_having_fit_object_with_update_bindings(self, factory_single_interface): + def test_switch_with_fitter_having_fit_object_with_update_bindings( + self, factory_single_interface + ): """Test switch with fitter that has _fit_object with update_bindings method""" # Given mock_fit_object = MagicMock() mock_fit_object.update_bindings = MagicMock() mock_fitter = MagicMock() mock_fitter._fit_object = mock_fit_object - + # When - factory_single_interface.switch("MockInterface1", fitter=mock_fitter) - + factory_single_interface.switch('MockInterface1', fitter=mock_fitter) + # Then mock_fit_object.update_bindings.assert_called_once() @@ -187,10 +197,10 @@ def test_switch_with_fitter_having_generate_bindings(self, factory_single_interf mock_fitter = MagicMock() mock_fitter.generate_bindings = MagicMock() del mock_fitter._fit_object # Ensure _fit_object doesn't exist - + # When - factory_single_interface.switch("MockInterface1", fitter=mock_fitter) - + factory_single_interface.switch('MockInterface1', fitter=mock_fitter) + # Then mock_fitter.generate_bindings.assert_called_once() @@ -198,64 +208,64 @@ def test_switch_with_fitter_exception_handling(self, factory_single_interface, c """Test switch handles exceptions in fitter binding updates gracefully""" # Given mock_fit_object = MagicMock() - mock_fit_object.update_bindings.side_effect = Exception("Test exception") + mock_fit_object.update_bindings.side_effect = Exception('Test exception') mock_fitter = MagicMock() mock_fitter._fit_object = mock_fit_object - + # When - factory_single_interface.switch("MockInterface1", fitter=mock_fitter) - + factory_single_interface.switch('MockInterface1', fitter=mock_fitter) + # Then captured = capsys.readouterr() - assert "Unable to auto generate bindings" in captured.out - assert "Test exception" in captured.out + assert 'Unable to auto generate bindings' in captured.out + assert 'Test exception' in captured.out def test_fit_func_property_returns_callable(self, factory_single_interface): """Test fit_func property returns a callable""" # When fit_func = factory_single_interface.fit_func - + # Then assert callable(fit_func) def test_fit_func_calls_interface_fit_func(self, factory_single_interface): """Test fit_func calls the underlying interface's fit_func""" # When - result = factory_single_interface.fit_func("arg1", kwarg1="value1") - + result = factory_single_interface.fit_func('arg1', kwarg1='value1') + # Then - assert result == "result1" + assert result == 'result1' def test_call_method(self, factory_single_interface): """Test call method delegates to fit_func""" # When - result = factory_single_interface.call("arg1", kwarg1="value1") - + result = factory_single_interface.call('arg1', kwarg1='value1') + # Then - assert result == "result1" + assert result == 'result1' def test_generate_bindings_with_matching_properties(self, factory_single_interface): """Test generate_bindings method with matching properties""" # Given mock_model = MagicMock() mock_prop = MagicMock() - mock_prop.name = "test_param" + mock_prop.name = 'test_param' mock_prop.value = 42 mock_model._get_linkable_attributes.return_value = [mock_prop] - + mock_item = MagicMock() - mock_item.name_conversion = {"test_param": "internal_param"} + mock_item.name_conversion = {'test_param': 'internal_param'} mock_item.make_prop.return_value = MagicMock() - + # Mock the interface object's create method interface_obj = factory_single_interface() interface_obj.create = MagicMock(return_value=[mock_item]) - + # When factory_single_interface.generate_bindings(mock_model) - + # Then - mock_item.make_prop.assert_called_once_with("test_param") + mock_item.make_prop.assert_called_once_with('test_param') assert mock_prop._callback is not None def test_generate_bindings_with_value_no_call_back_property(self, factory_single_interface): @@ -263,22 +273,22 @@ def test_generate_bindings_with_value_no_call_back_property(self, factory_single # Given mock_model = MagicMock() mock_prop = MagicMock() - mock_prop.name = "test_param" + mock_prop.name = 'test_param' mock_prop.value_no_call_back = 24 mock_model._get_linkable_attributes.return_value = [mock_prop] - + mock_item = MagicMock() - mock_item.name_conversion = {"test_param": "internal_param"} + mock_item.name_conversion = {'test_param': 'internal_param'} mock_callback = MagicMock() mock_item.make_prop.return_value = mock_callback - + # Mock the interface object's create method interface_obj = factory_single_interface() interface_obj.create = MagicMock(return_value=[mock_item]) - + # When factory_single_interface.generate_bindings(mock_model) - + # Then mock_callback.fset.assert_called_once_with(24) @@ -287,19 +297,19 @@ def test_generate_bindings_skips_non_matching_properties(self, factory_single_in # Given mock_model = MagicMock() mock_prop = MagicMock() - mock_prop.name = "non_matching_param" + mock_prop.name = 'non_matching_param' mock_model._get_linkable_attributes.return_value = [mock_prop] - + mock_item = MagicMock() - mock_item.name_conversion = {"different_param": "internal_param"} - + mock_item.name_conversion = {'different_param': 'internal_param'} + # Mock the interface object's create method interface_obj = factory_single_interface() interface_obj.create = MagicMock(return_value=[mock_item]) - + # When factory_single_interface.generate_bindings(mock_model) - + # Then mock_item.make_prop.assert_not_called() @@ -308,7 +318,7 @@ def test_call_dunder_method_returns_interface_obj(self, factory_single_interface # When result1 = factory_single_interface() result2 = factory_single_interface() - + # Then assert result1 is not None assert result1 is result2 # Should return the same object @@ -317,80 +327,84 @@ def test_reduce_method_for_pickle_support(self, factory_single_interface): """Test __reduce__ method for pickle serialization support""" # When result = factory_single_interface.__reduce__() - + # Then assert len(result) == 2 assert result[0] == InterfaceFactoryTemplate.__state_restore__ assert result[1][0] == InterfaceFactoryTemplate - assert result[1][1] == "MockInterface1" + assert result[1][1] == 'MockInterface1' - def test_state_restore_static_method_implementation_issue(self, clear, mock_interface1, mock_interface2): + def test_state_restore_static_method_implementation_issue( + self, clear, mock_interface1, mock_interface2 + ): """Test __state_restore__ static method - demonstrates implementation issue""" # Given original_factory = InterfaceFactoryTemplate([mock_interface1, mock_interface2]) - + # When/Then - this implementation has a bug where it tries to call cls() without arguments # which would fail since the constructor requires interface_list parameter with pytest.raises(TypeError): - InterfaceFactoryTemplate.__state_restore__( - InterfaceFactoryTemplate, "MockInterface2" - ) + InterfaceFactoryTemplate.__state_restore__(InterfaceFactoryTemplate, 'MockInterface2') def test_return_name_static_method_with_name_attribute(self, mock_interface_with_custom_name): """Test return_name static method with interface having name attribute""" # When name = InterfaceFactoryTemplate.return_name(mock_interface_with_custom_name) - + # Then - assert name == "CustomName" + assert name == 'CustomName' def test_return_name_static_method_without_name_attribute(self, mock_interface1): """Test return_name static method without name attribute uses __name__""" # When name = InterfaceFactoryTemplate.return_name(mock_interface1) - + # Then - assert name == "MockInterface1" + assert name == 'MockInterface1' - def test_switch_with_fitter_generate_bindings_exception(self, factory_single_interface, capsys): + def test_switch_with_fitter_generate_bindings_exception( + self, factory_single_interface, capsys + ): """Test switch handles exceptions in fitter.generate_bindings gracefully""" # Given mock_fitter = MagicMock() - mock_fitter.generate_bindings.side_effect = Exception("Generate bindings test exception") + mock_fitter.generate_bindings.side_effect = Exception('Generate bindings test exception') # Ensure _fit_object doesn't exist so it goes to the elif branch if hasattr(mock_fitter, '_fit_object'): del mock_fitter._fit_object - + # When - factory_single_interface.switch("MockInterface1", fitter=mock_fitter) - + factory_single_interface.switch('MockInterface1', fitter=mock_fitter) + # Then captured = capsys.readouterr() - assert "Unable to auto generate bindings" in captured.out - assert "Generate bindings test exception" in captured.out + assert 'Unable to auto generate bindings' in captured.out + assert 'Generate bindings test exception' in captured.out - def test_generate_bindings_with_property_without_value_no_call_back(self, factory_single_interface): + def test_generate_bindings_with_property_without_value_no_call_back( + self, factory_single_interface + ): """Test generate_bindings handles properties without value_no_call_back (descriptor objects)""" # Given mock_model = MagicMock() mock_prop = MagicMock() - mock_prop.name = "test_param" + mock_prop.name = 'test_param' mock_prop.value = 99 # This will be used since no value_no_call_back attribute # Explicitly remove value_no_call_back to force the else branch del mock_prop.value_no_call_back mock_model._get_linkable_attributes.return_value = [mock_prop] - + mock_item = MagicMock() - mock_item.name_conversion = {"test_param": "internal_param"} + mock_item.name_conversion = {'test_param': 'internal_param'} mock_callback = MagicMock() mock_item.make_prop.return_value = mock_callback - + interface_obj = factory_single_interface() interface_obj.create = MagicMock(return_value=[mock_item]) - + # When factory_single_interface.generate_bindings(mock_model) - + # Then mock_callback.fset.assert_called_once_with(99) @@ -399,56 +413,63 @@ class TestItemContainer: @pytest.fixture def mock_getter(self): """Mock getter function""" + def getter(link_name, key): - return f"got_{link_name}_{key}" + return f'got_{link_name}_{key}' + return getter - + @pytest.fixture def mock_setter(self): """Mock setter function""" + def setter(link_name, **kwargs): pass + return setter - + @pytest.fixture def item_container(self, mock_getter, mock_setter): """Create ItemContainer instance""" return ItemContainer( - link_name="test_link", - name_conversion={"param1": "internal_param1", "param2": "internal_param2"}, + link_name='test_link', + name_conversion={'param1': 'internal_param1', 'param2': 'internal_param2'}, getter_fn=mock_getter, - setter_fn=mock_setter + setter_fn=mock_setter, ) def test_item_container_creation(self, item_container): """Test ItemContainer can be created with required fields""" # Then - assert item_container.link_name == "test_link" - assert item_container.name_conversion == {"param1": "internal_param1", "param2": "internal_param2"} + assert item_container.link_name == 'test_link' + assert item_container.name_conversion == { + 'param1': 'internal_param1', + 'param2': 'internal_param2', + } assert callable(item_container.getter_fn) assert callable(item_container.setter_fn) def test_convert_key_with_existing_key(self, item_container): """Test convert_key method with existing key""" # When - result = item_container.convert_key("param1") - + result = item_container.convert_key('param1') + # Then - assert result == "internal_param1" + assert result == 'internal_param1' def test_convert_key_with_non_existing_key(self, item_container): """Test convert_key method with non-existing key returns None""" # When - result = item_container.convert_key("non_existing") - + result = item_container.convert_key('non_existing') + # Then assert result is None def test_make_prop_returns_property(self, item_container): """Test make_prop method returns a property object""" # When - prop = item_container.make_prop("param1") - + prop = item_container.make_prop('param1') + # Then assert isinstance(prop, property) assert prop.fget is not None @@ -457,8 +478,8 @@ def test_make_prop_returns_property(self, item_container): def test_make_getter_function_behavior(self, item_container): """Test the behavior of the __make_getter method indirectly""" # When - prop = item_container.make_prop("param1") - + prop = item_container.make_prop('param1') + # Then assert isinstance(prop, property) assert prop.fget is not None @@ -468,20 +489,20 @@ def test_make_setter_function_behavior(self, item_container): """Test the behavior of the __make_setter method indirectly""" # Given setter_calls = [] - + def mock_setter(link_name, **kwargs): setter_calls.append((link_name, kwargs)) - + container = ItemContainer( - link_name="test_link", - name_conversion={"param1": "internal_param1"}, + link_name='test_link', + name_conversion={'param1': 'internal_param1'}, getter_fn=lambda x, y: None, - setter_fn=mock_setter + setter_fn=mock_setter, ) - + # When - prop = container.make_prop("param1") - + prop = container.make_prop('param1') + # Then assert isinstance(prop, property) assert prop.fset is not None @@ -490,12 +511,12 @@ def mock_setter(link_name, **kwargs): def test_convert_key_behavior_in_property_creation(self, item_container): """Test that convert_key behavior is used correctly in property creation""" # When - prop1 = item_container.make_prop("param1") # exists in name_conversion - prop2 = item_container.make_prop("non_existing_param") # doesn't exist - + prop1 = item_container.make_prop('param1') # exists in name_conversion + prop2 = item_container.make_prop('non_existing_param') # doesn't exist + # Then # Both should create valid property objects - assert isinstance(prop1, property) + assert isinstance(prop1, property) assert isinstance(prop2, property) # The difference is in the internal key mapping which affects runtime behavior @@ -504,37 +525,36 @@ def test_actual_getter_setter_execution(self): # Given getter_calls = [] setter_calls = [] - + def mock_getter(link_name, key): getter_calls.append((link_name, key)) - return f"value_for_{key}" - + return f'value_for_{key}' + def mock_setter(link_name, **kwargs): setter_calls.append((link_name, kwargs)) - + container = ItemContainer( - link_name="test_link", - name_conversion={"param1": "internal_param1"}, + link_name='test_link', + name_conversion={'param1': 'internal_param1'}, getter_fn=mock_getter, - setter_fn=mock_setter + setter_fn=mock_setter, ) - + # When - prop = container.make_prop("param1") - + prop = container.make_prop('param1') + # Execute the getter function directly (this covers the actual getter execution) getter_func = prop.fget getter_result = getter_func() # type: ignore - + # Execute the setter function directly (this covers the actual setter execution) setter_func = prop.fset - setter_func("test_value") # type: ignore - + setter_func('test_value') # type: ignore + # Then - assert getter_result == "value_for_internal_param1" + assert getter_result == 'value_for_internal_param1' assert len(getter_calls) == 1 - assert getter_calls[0] == ("test_link", "internal_param1") - - assert len(setter_calls) == 1 - assert setter_calls[0] == ("test_link", {"internal_param1": "test_value"}) + assert getter_calls[0] == ('test_link', 'internal_param1') + assert len(setter_calls) == 1 + assert setter_calls[0] == ('test_link', {'internal_param1': 'test_value'}) diff --git a/tests/unit/fitting/minimizers/__init__.py b/tests/unit/fitting/minimizers/__init__.py new file mode 100644 index 00000000..b1990ec8 --- /dev/null +++ b/tests/unit/fitting/minimizers/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + diff --git a/tests/unit_tests/fitting/minimizers/test_factory.py b/tests/unit/fitting/minimizers/test_factory.py similarity index 51% rename from tests/unit_tests/fitting/minimizers/test_factory.py rename to tests/unit/fitting/minimizers/test_factory.py index 323ce8b7..8ee4df6c 100644 --- a/tests/unit_tests/fitting/minimizers/test_factory.py +++ b/tests/unit/fitting/minimizers/test_factory.py @@ -1,9 +1,15 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + +from unittest.mock import MagicMock + +import pytest + from easyscience import AvailableMinimizers -from easyscience.fitting.minimizers.factory import factory from easyscience.fitting.available_minimizers import from_string_to_enum from easyscience.fitting.minimizers import MinimizerBase -from unittest.mock import MagicMock -import pytest +from easyscience.fitting.minimizers.factory import factory + class TestFactory: def pull_minminizer(self, minimizer: AvailableMinimizers) -> MinimizerBase: @@ -12,36 +18,78 @@ def pull_minminizer(self, minimizer: AvailableMinimizers) -> MinimizerBase: minimizer = factory(minimizer, mock_fit_object, mock_fit_function) return minimizer - @pytest.mark.parametrize('minimizer_method,minimizer_enum', [('leastsq', AvailableMinimizers.LMFit), ('leastsq', AvailableMinimizers.LMFit_leastsq), ('powell', AvailableMinimizers.LMFit_powell), ('cobyla', AvailableMinimizers.LMFit_cobyla), ('differential_evolution', AvailableMinimizers.LMFit_differential_evolution), ('least_squares', AvailableMinimizers.LMFit_scipy_least_squares)]) + @pytest.mark.parametrize( + 'minimizer_method,minimizer_enum', + [ + ('leastsq', AvailableMinimizers.LMFit), + ('leastsq', AvailableMinimizers.LMFit_leastsq), + ('powell', AvailableMinimizers.LMFit_powell), + ('cobyla', AvailableMinimizers.LMFit_cobyla), + ('differential_evolution', AvailableMinimizers.LMFit_differential_evolution), + ('least_squares', AvailableMinimizers.LMFit_scipy_least_squares), + ], + ) def test_factory_lm_fit(self, minimizer_method, minimizer_enum): minimizer = self.pull_minminizer(minimizer_enum) assert minimizer._method == minimizer_method assert minimizer.package == 'lmfit' - @pytest.mark.parametrize('minimizer_method,minimizer_enum', [('amoeba', AvailableMinimizers.Bumps), ('amoeba', AvailableMinimizers.Bumps_simplex), ('newton', AvailableMinimizers.Bumps_newton), ('lm', AvailableMinimizers.Bumps_lm)]) + @pytest.mark.parametrize( + 'minimizer_method,minimizer_enum', + [ + ('amoeba', AvailableMinimizers.Bumps), + ('amoeba', AvailableMinimizers.Bumps_simplex), + ('newton', AvailableMinimizers.Bumps_newton), + ('lm', AvailableMinimizers.Bumps_lm), + ], + ) def test_factory_bumps_fit(self, minimizer_method, minimizer_enum): minimizer = self.pull_minminizer(minimizer_enum) assert minimizer._method == minimizer_method assert minimizer.package == 'bumps' - @pytest.mark.parametrize('minimizer_method,minimizer_enum', [('leastsq', AvailableMinimizers.DFO), ('leastsq', AvailableMinimizers.DFO_leastsq)]) + @pytest.mark.parametrize( + 'minimizer_method,minimizer_enum', + [('leastsq', AvailableMinimizers.DFO), ('leastsq', AvailableMinimizers.DFO_leastsq)], + ) def test_factory_dfo_fit(self, minimizer_method, minimizer_enum): minimizer = self.pull_minminizer(minimizer_enum) assert minimizer._method == minimizer_method assert minimizer.package == 'dfo' -@pytest.mark.parametrize('minimizer_name,expected', [('LMFit', AvailableMinimizers.LMFit), ('LMFit_leastsq', AvailableMinimizers.LMFit_leastsq), ('LMFit_powell', AvailableMinimizers.LMFit_powell), ('LMFit_cobyla', AvailableMinimizers.LMFit_cobyla), ('LMFit_differential_evolution', AvailableMinimizers.LMFit_differential_evolution), ('LMFit_scipy_least_squares', AvailableMinimizers.LMFit_scipy_least_squares) ]) +@pytest.mark.parametrize( + 'minimizer_name,expected', + [ + ('LMFit', AvailableMinimizers.LMFit), + ('LMFit_leastsq', AvailableMinimizers.LMFit_leastsq), + ('LMFit_powell', AvailableMinimizers.LMFit_powell), + ('LMFit_cobyla', AvailableMinimizers.LMFit_cobyla), + ('LMFit_differential_evolution', AvailableMinimizers.LMFit_differential_evolution), + ('LMFit_scipy_least_squares', AvailableMinimizers.LMFit_scipy_least_squares), + ], +) def test_from_string_to_enum_lmfit(minimizer_name, expected): assert from_string_to_enum(minimizer_name) == expected -@pytest.mark.parametrize('minimizer_name,expected', [('Bumps', AvailableMinimizers.Bumps), ('Bumps_simplex', AvailableMinimizers.Bumps_simplex), ('Bumps_newton', AvailableMinimizers.Bumps_newton), ('Bumps_lm', AvailableMinimizers.Bumps_lm)]) +@pytest.mark.parametrize( + 'minimizer_name,expected', + [ + ('Bumps', AvailableMinimizers.Bumps), + ('Bumps_simplex', AvailableMinimizers.Bumps_simplex), + ('Bumps_newton', AvailableMinimizers.Bumps_newton), + ('Bumps_lm', AvailableMinimizers.Bumps_lm), + ], +) def test_from_string_to_enum_bumps(minimizer_name, expected): assert from_string_to_enum(minimizer_name) == expected -@pytest.mark.parametrize('minimizer_name,expected', [('DFO', AvailableMinimizers.DFO), ('DFO_leastsq', AvailableMinimizers.DFO_leastsq)]) +@pytest.mark.parametrize( + 'minimizer_name,expected', + [('DFO', AvailableMinimizers.DFO), ('DFO_leastsq', AvailableMinimizers.DFO_leastsq)], +) def test_from_string_to_enum_dfo(minimizer_name, expected): assert from_string_to_enum(minimizer_name) == expected @@ -59,4 +107,4 @@ def test_available_minimizers(): assert AvailableMinimizers.Bumps_lm assert AvailableMinimizers.DFO assert AvailableMinimizers.DFO_leastsq - assert len(AvailableMinimizers) == 12 \ No newline at end of file + assert len(AvailableMinimizers) == 12 diff --git a/tests/unit_tests/fitting/minimizers/test_minimizer_base.py b/tests/unit/fitting/minimizers/test_minimizer_base.py similarity index 78% rename from tests/unit_tests/fitting/minimizers/test_minimizer_base.py rename to tests/unit/fitting/minimizers/test_minimizer_base.py index e4fcb005..86ec4292 100644 --- a/tests/unit_tests/fitting/minimizers/test_minimizer_base.py +++ b/tests/unit/fitting/minimizers/test_minimizer_base.py @@ -1,30 +1,31 @@ -import pytest - -from unittest.mock import MagicMock +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause from inspect import Parameter as InspectParameter from inspect import Signature from inspect import _empty +from unittest.mock import MagicMock + +import pytest +from easyscience import Parameter from easyscience.fitting.minimizers.minimizer_base import MinimizerBase from easyscience.fitting.minimizers.utils import FitError -from easyscience import Parameter -class TestMinimizerBase(): + +class TestMinimizerBase: @pytest.fixture def minimizer(self): # This avoids the error: TypeError: Can't instantiate abstract class with abstract methods __init__ MinimizerBase.__abstractmethods__ = set() MinimizerBase.supported_methods = MagicMock(return_value=['method']) - self._mock_minimizer_enum = MagicMock(package='package', method='method') + self._mock_minimizer_enum = MagicMock(package='package', method='method') minimizer = MinimizerBase( - obj='obj', - fit_function='fit_function', - minimizer_enum=self._mock_minimizer_enum + obj='obj', fit_function='fit_function', minimizer_enum=self._mock_minimizer_enum ) return minimizer - + def test_init_exception(self): # When Then MinimizerBase.__abstractmethods__ = set() @@ -34,8 +35,8 @@ def test_init_exception(self): with pytest.raises(FitError): MinimizerBase( obj='obj', - fit_function='fit_function', - minimizer_enum=MagicMock(package='package', method='not_a_method') + fit_function='fit_function', + minimizer_enum=MagicMock(package='package', method='not_a_method'), ) def test_init(self, minimizer: MinimizerBase): @@ -46,35 +47,51 @@ def test_init(self, minimizer: MinimizerBase): assert minimizer._cached_pars_vals == {} assert minimizer._cached_model == None assert minimizer._fit_function == None - + def test_enum(self, minimizer: MinimizerBase): assert minimizer.enum == self._mock_minimizer_enum def test_evaluate(self, minimizer: MinimizerBase): # When minimizer._fit_function = MagicMock(return_value='fit_function_return') - minimizer._prepare_parameters = MagicMock(return_value={'prepared_parms_key': 'prepared_parms_val'}) + minimizer._prepare_parameters = MagicMock( + return_value={'prepared_parms_key': 'prepared_parms_val'} + ) # Then - result = minimizer.evaluate('x', minimizer_parameters={'parms_key': 'parms_val'}, kwargs={'kwargs_key': 'kwargs_val'}) + result = minimizer.evaluate( + 'x', + minimizer_parameters={'parms_key': 'parms_val'}, + kwargs={'kwargs_key': 'kwargs_val'}, + ) # Expect assert result == 'fit_function_return' - minimizer._fit_function.assert_called_once_with('x', prepared_parms_key='prepared_parms_val', kwargs={'kwargs_key': 'kwargs_val'}) + minimizer._fit_function.assert_called_once_with( + 'x', prepared_parms_key='prepared_parms_val', kwargs={'kwargs_key': 'kwargs_val'} + ) minimizer._prepare_parameters.assert_called_once_with({'parms_key': 'parms_val'}) def test_evaluate_no_fit_function(self, minimizer: MinimizerBase): # When mock_fit_function = MagicMock() minimizer._fit_function = None - minimizer._prepare_parameters = MagicMock(return_value={'prepared_parms_key': 'prepared_parms_val'}) + minimizer._prepare_parameters = MagicMock( + return_value={'prepared_parms_key': 'prepared_parms_val'} + ) minimizer._generate_fit_function = MagicMock(return_value=mock_fit_function) # Then - minimizer.evaluate('x', minimizer_parameters={'parms_key': 'parms_val'}, kwargs={'kwargs_key': 'kwargs_val'}) + minimizer.evaluate( + 'x', + minimizer_parameters={'parms_key': 'parms_val'}, + kwargs={'kwargs_key': 'kwargs_val'}, + ) # Expect - mock_fit_function.assert_called_once_with('x', prepared_parms_key='prepared_parms_val', kwargs={'kwargs_key': 'kwargs_val'}) + mock_fit_function.assert_called_once_with( + 'x', prepared_parms_key='prepared_parms_val', kwargs={'kwargs_key': 'kwargs_val'} + ) minimizer._prepare_parameters.assert_called_once_with({'parms_key': 'parms_val'}) def test_evaluate_no_parameters(self, minimizer: MinimizerBase): @@ -99,16 +116,9 @@ def test_evaluate_exception(self, minimizer: MinimizerBase): def test_prepare_parameters(self, minimizer: MinimizerBase): # When - parameters = { - 'pa': 1, - 'pb': 2 - } - - minimizer._cached_pars = { - 'a': MagicMock(), - 'b': MagicMock(), - 'c': MagicMock() - } + parameters = {'pa': 1, 'pb': 2} + + minimizer._cached_pars = {'a': MagicMock(), 'b': MagicMock(), 'c': MagicMock()} minimizer._cached_pars['a'].value = 3 minimizer._cached_pars['b'].value = 4 minimizer._cached_pars['c'].value = 5 @@ -117,11 +127,7 @@ def test_prepare_parameters(self, minimizer: MinimizerBase): parameters = minimizer._prepare_parameters(parameters) # Expect - assert parameters == { - 'pa': 1, - 'pb': 2, - 'pc': 5 - } + assert parameters == {'pa': 1, 'pb': 2, 'pc': 5} def test_generate_fit_function(self, minimizer: MinimizerBase) -> None: # When @@ -159,12 +165,16 @@ def test_create_signature(self, minimizer: MinimizerBase) -> None: # Then signature = minimizer._create_signature(pars) - + # Expect wrapped_parameters = [ InspectParameter('x', InspectParameter.POSITIONAL_OR_KEYWORD, annotation=_empty), - InspectParameter('p1', InspectParameter.POSITIONAL_OR_KEYWORD, annotation=_empty, default=1.0), - InspectParameter('p2', InspectParameter.POSITIONAL_OR_KEYWORD, annotation=_empty, default=2.0) + InspectParameter( + 'p1', InspectParameter.POSITIONAL_OR_KEYWORD, annotation=_empty, default=1.0 + ), + InspectParameter( + 'p2', InspectParameter.POSITIONAL_OR_KEYWORD, annotation=_empty, default=2.0 + ), ] expected_signature = Signature(wrapped_parameters) assert signature == expected_signature @@ -177,7 +187,7 @@ def test_get_method_dict(self, minimizer: MinimizerBase) -> None: assert result == {'method': 'method'} def test_get_method_dict_no_self(self, minimizer: MinimizerBase) -> None: - # When + # When minimizer._method = None # Then @@ -203,4 +213,3 @@ def test_get_method_dict_not_supported_method(self, minimizer: MinimizerBase) -> # Then Expect with pytest.raises(FitError): result = minimizer._get_method_kwargs('not_supported_method') - diff --git a/tests/unit_tests/fitting/minimizers/test_minimizer_bumps.py b/tests/unit/fitting/minimizers/test_minimizer_bumps.py similarity index 77% rename from tests/unit_tests/fitting/minimizers/test_minimizer_bumps.py rename to tests/unit/fitting/minimizers/test_minimizer_bumps.py index 703b0617..ba86b4d0 100644 --- a/tests/unit_tests/fitting/minimizers/test_minimizer_bumps.py +++ b/tests/unit/fitting/minimizers/test_minimizer_bumps.py @@ -1,21 +1,23 @@ -import pytest +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause from unittest.mock import MagicMock + import numpy as np +import pytest import easyscience.fitting.minimizers.minimizer_bumps - from easyscience.fitting.minimizers.minimizer_bumps import Bumps from easyscience.fitting.minimizers.utils import FitError -class TestBumpsFit(): +class TestBumpsFit: @pytest.fixture def minimizer(self) -> Bumps: minimizer = Bumps( obj='obj', - fit_function='fit_function', - minimizer_enum=MagicMock(package='bumps', method='amoeba') + fit_function='fit_function', + minimizer_enum=MagicMock(package='bumps', method='amoeba'), ) return minimizer @@ -27,8 +29,8 @@ def test_init_exception(self) -> None: with pytest.raises(FitError): Bumps( obj='obj', - fit_function='fit_function', - minimizer_enum=MagicMock(package='bumps', method='not_amoeba') + fit_function='fit_function', + minimizer_enum=MagicMock(package='bumps', method='not_amoeba'), ) def test_all_methods(self, minimizer: Bumps) -> None: @@ -42,10 +44,13 @@ def test_supported_methods(self, minimizer: Bumps) -> None: def test_fit(self, minimizer: Bumps, monkeypatch) -> None: # When from easyscience import global_object + global_object.stack.enabled = False mock_bumps_fit = MagicMock(return_value='fit') - monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_bumps, "bumps_fit", mock_bumps_fit) + monkeypatch.setattr( + easyscience.fitting.minimizers.minimizer_bumps, 'bumps_fit', mock_bumps_fit + ) # Prepare a mock parameter with .name = 'pmock_parm_1' mock_bumps_param = MagicMock() @@ -54,7 +59,9 @@ def test_fit(self, minimizer: Bumps, monkeypatch) -> None: mock_FitProblem_instance = MagicMock() mock_FitProblem_instance._parameters = [mock_bumps_param] mock_FitProblem = MagicMock(return_value=mock_FitProblem_instance) - monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_bumps, "FitProblem", mock_FitProblem) + monkeypatch.setattr( + easyscience.fitting.minimizers.minimizer_bumps, 'FitProblem', mock_FitProblem + ) mock_model = MagicMock() mock_model_function = MagicMock(return_value=mock_model) @@ -70,8 +77,9 @@ def test_fit(self, minimizer: Bumps, monkeypatch) -> None: def fake_set_parameter_fit_result(fit_result, stack_status, par_list): # Simulate what the real function does: update _cached_pars for index, name in enumerate([par.name for par in par_list]): - dict_name = name[len('p'):] # Remove prefix 'p' + dict_name = name[len('p') :] # Remove prefix 'p' minimizer._cached_pars[dict_name].value = 42 # Arbitrary value + minimizer._set_parameter_fit_result = fake_set_parameter_fit_result # Then @@ -85,12 +93,22 @@ def fake_set_parameter_fit_result(fit_result, stack_status, par_list): mock_model_function.assert_called_once_with(1.0, 2.0, 1) mock_FitProblem.assert_called_once_with(mock_model) - @pytest.mark.parametrize("weights", [np.array([1, 2, 3, 4]), np.array([[1, 2, 3], [4, 5, 6]]), np.repeat(np.nan,3), np.zeros(3), np.repeat(np.inf,3), -np.ones(3)], ids=["wrong_length", "multidimensional", "NaNs", "zeros", "Infs", "negative"]) + @pytest.mark.parametrize( + 'weights', + [ + np.array([1, 2, 3, 4]), + np.array([[1, 2, 3], [4, 5, 6]]), + np.repeat(np.nan, 3), + np.zeros(3), + np.repeat(np.inf, 3), + -np.ones(3), + ], + ids=['wrong_length', 'multidimensional', 'NaNs', 'zeros', 'Infs', 'negative'], + ) def test_fit_weight_exceptions(self, minimizer: Bumps, weights) -> None: # When Then Expect with pytest.raises(ValueError): minimizer.fit(x=np.array([1, 2, 3]), y=np.array([1, 2, 3]), weights=weights) - def test_make_model(self, minimizer: Bumps, monkeypatch) -> None: # When @@ -99,20 +117,22 @@ def test_make_model(self, minimizer: Bumps, monkeypatch) -> None: mock_parm_1 = MagicMock() mock_parm_1.unique_name = 'mock_parm_1' - minimizer.convert_to_par_object = MagicMock(return_value='converted_parm_1') + minimizer.convert_to_par_object = MagicMock(return_value='converted_parm_1') mock_Curve = MagicMock(return_value='curve') - monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_bumps, "Curve", mock_Curve) + monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_bumps, 'Curve', mock_Curve) # Then model = minimizer._make_model(parameters=[mock_parm_1]) - curve_for_model = model(x=np.array([1, 2]), y=np.array([10, 20]), weights=np.array([100, 200])) + curve_for_model = model( + x=np.array([1, 2]), y=np.array([10, 20]), weights=np.array([100, 200]) + ) # Expect minimizer._generate_fit_function.assert_called_once_with() assert mock_Curve.call_args[0][0] == mock_fit_function - assert all(mock_Curve.call_args[0][1] == np.array([1,2])) - assert all(mock_Curve.call_args[0][2] == np.array([10,20])) + assert all(mock_Curve.call_args[0][1] == np.array([1, 2])) + assert all(mock_Curve.call_args[0][2] == np.array([10, 20])) assert curve_for_model == 'curve' def test_set_parameter_fit_result_no_stack_status(self, minimizer: Bumps): @@ -125,7 +145,7 @@ def test_set_parameter_fit_result_no_stack_status(self, minimizer: Bumps): minimizer._cached_pars['b'].value = 'b' mock_cached_model = MagicMock() - mock_cached_model.pars = {'pa':0, 'pb': 0} + mock_cached_model.pars = {'pa': 0, 'pb': 0} minimizer._cached_model = mock_cached_model mock_fit_result = MagicMock() @@ -152,7 +172,9 @@ def test_gen_fit_results(self, minimizer: Bumps, monkeypatch): # When mock_domain_fit_results = MagicMock() mock_FitResults = MagicMock(return_value=mock_domain_fit_results) - monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_bumps, "FitResults", mock_FitResults) + monkeypatch.setattr( + easyscience.fitting.minimizers.minimizer_bumps, 'FitResults', mock_FitResults + ) mock_fit_result = MagicMock() mock_fit_result.success = True @@ -170,22 +192,29 @@ def test_gen_fit_results(self, minimizer: Bumps, monkeypatch): mock_cached_par_2.value = 'par_value_2' minimizer._cached_pars = {'par_1': mock_cached_par_1, 'par_2': mock_cached_par_2} - minimizer._p_0 = 'p_0' + minimizer._p_0 = 'p_0' minimizer.evaluate = MagicMock(return_value='evaluate') # Then - domain_fit_results = minimizer._gen_fit_results(mock_fit_result, **{'kwargs_set_key': 'kwargs_set_val'}) + domain_fit_results = minimizer._gen_fit_results( + mock_fit_result, **{'kwargs_set_key': 'kwargs_set_val'} + ) # Expect assert domain_fit_results == mock_domain_fit_results assert domain_fit_results.kwargs_set_key == 'kwargs_set_val' - assert domain_fit_results.success == True + assert domain_fit_results.success == True assert domain_fit_results.y_obs == 'y' assert domain_fit_results.x == 'x' assert domain_fit_results.p == {'ppar_1': 'par_value_1', 'ppar_2': 'par_value_2'} assert domain_fit_results.p0 == 'p_0' assert domain_fit_results.y_calc == 'evaluate' assert domain_fit_results.y_err == 'dy' - assert str(domain_fit_results.minimizer_engine) == "" + assert ( + str(domain_fit_results.minimizer_engine) + == "" + ) assert domain_fit_results.fit_args is None - minimizer.evaluate.assert_called_once_with('x', minimizer_parameters={'ppar_1': 'par_value_1', 'ppar_2': 'par_value_2'}) + minimizer.evaluate.assert_called_once_with( + 'x', minimizer_parameters={'ppar_1': 'par_value_1', 'ppar_2': 'par_value_2'} + ) diff --git a/tests/unit_tests/fitting/minimizers/test_minimizer_dfo.py b/tests/unit/fitting/minimizers/test_minimizer_dfo.py similarity index 58% rename from tests/unit_tests/fitting/minimizers/test_minimizer_dfo.py rename to tests/unit/fitting/minimizers/test_minimizer_dfo.py index 439afea0..e1d5eeef 100644 --- a/tests/unit_tests/fitting/minimizers/test_minimizer_dfo.py +++ b/tests/unit/fitting/minimizers/test_minimizer_dfo.py @@ -1,44 +1,46 @@ -import pytest +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause from unittest.mock import MagicMock + import numpy as np +import pytest import easyscience.fitting.minimizers.minimizer_dfo -from easyscience.variable import Parameter - from easyscience.fitting.minimizers.minimizer_dfo import DFO from easyscience.fitting.minimizers.utils import FitError +from easyscience.variable import Parameter class TestDFOFit: @pytest.fixture def minimizer(self) -> DFO: minimizer = DFO( - obj="obj", - fit_function="fit_function", - minimizer_enum=MagicMock(package="dfo", method="leastsq"), + obj='obj', + fit_function='fit_function', + minimizer_enum=MagicMock(package='dfo', method='leastsq'), ) return minimizer def test_init(self, minimizer: DFO) -> None: assert minimizer._p_0 == {} - assert minimizer.package == "dfo" + assert minimizer.package == 'dfo' def test_init_exception(self) -> None: with pytest.raises(FitError): DFO( - obj="obj", - fit_function="fit_function", - minimizer_enum=MagicMock(package="dfo", method="not_leastsq"), + obj='obj', + fit_function='fit_function', + minimizer_enum=MagicMock(package='dfo', method='not_leastsq'), ) def test_supported_methods(self, minimizer: DFO) -> None: # When Then Expect - assert minimizer.supported_methods() == ["leastsq"] + assert minimizer.supported_methods() == ['leastsq'] def test_supported_methods(self, minimizer: DFO) -> None: # When Then Expect - assert minimizer.supported_methods() == ["leastsq"] + assert minimizer.supported_methods() == ['leastsq'] def test_fit(self, minimizer: DFO) -> None: # When @@ -49,55 +51,53 @@ def test_fit(self, minimizer: DFO) -> None: mock_model = MagicMock() mock_model_function = MagicMock(return_value=mock_model) minimizer._make_model = MagicMock(return_value=mock_model_function) - minimizer._dfo_fit = MagicMock(return_value="fit") + minimizer._dfo_fit = MagicMock(return_value='fit') minimizer._set_parameter_fit_result = MagicMock() - minimizer._gen_fit_results = MagicMock(return_value="gen_fit_results") + minimizer._gen_fit_results = MagicMock(return_value='gen_fit_results') cached_par = MagicMock() cached_par.value = 1 - cached_pars = {"mock_parm_1": cached_par} + cached_pars = {'mock_parm_1': cached_par} minimizer._cached_pars = cached_pars # Then result = minimizer.fit(x=1.0, y=2.0, weights=1) # Expect - assert result == "gen_fit_results" + assert result == 'gen_fit_results' minimizer._dfo_fit.assert_called_once_with(cached_pars, mock_model) minimizer._make_model.assert_called_once_with(parameters=None) - minimizer._set_parameter_fit_result.assert_called_once_with("fit", False) - minimizer._gen_fit_results.assert_called_once_with("fit", 1) + minimizer._set_parameter_fit_result.assert_called_once_with('fit', False) + minimizer._gen_fit_results.assert_called_once_with('fit', 1) mock_model_function.assert_called_once_with(1.0, 2.0, 1) def test_generate_fit_function(self, minimizer: DFO) -> None: # When - minimizer._original_fit_function = MagicMock(return_value="fit_function_result") + minimizer._original_fit_function = MagicMock(return_value='fit_function_result') minimizer._object = MagicMock() mock_parm_1 = MagicMock() - mock_parm_1.unique_name = "mock_parm_1" + mock_parm_1.unique_name = 'mock_parm_1' mock_parm_1.value = 1.0 mock_parm_1.error = 0.1 mock_parm_2 = MagicMock() - mock_parm_2.unique_name = "mock_parm_2" + mock_parm_2.unique_name = 'mock_parm_2' mock_parm_2.value = 2.0 mock_parm_2.error = 0.2 - minimizer._object.get_fit_parameters = MagicMock( - return_value=[mock_parm_1, mock_parm_2] - ) + minimizer._object.get_fit_parameters = MagicMock(return_value=[mock_parm_1, mock_parm_2]) # Then fit_function = minimizer._generate_fit_function() fit_function_result = fit_function([10.0]) # Expect - assert "fit_function_result" == fit_function_result + assert 'fit_function_result' == fit_function_result minimizer._original_fit_function.assert_called_once_with([10.0]) - assert minimizer._cached_pars["mock_parm_1"] == mock_parm_1 - assert minimizer._cached_pars["mock_parm_2"] == mock_parm_2 + assert minimizer._cached_pars['mock_parm_1'] == mock_parm_1 + assert minimizer._cached_pars['mock_parm_2'] == mock_parm_2 @pytest.mark.parametrize( - "weights", + 'weights', [ np.array([1, 2, 3, 4]), np.array([[1, 2, 3], [4, 5, 6]]), @@ -106,7 +106,7 @@ def test_generate_fit_function(self, minimizer: DFO) -> None: np.repeat(np.inf, 3), -np.ones(3), ], - ids=["wrong_length", "multidimensional", "NaNs", "zeros", "Infs", "negative"], + ids=['wrong_length', 'multidimensional', 'NaNs', 'zeros', 'Infs', 'negative'], ) def test_fit_weight_exceptions(self, minimizer: DFO, weights) -> None: # When Then Expect @@ -119,10 +119,10 @@ def test_make_model(self, minimizer: DFO) -> None: minimizer._generate_fit_function = MagicMock(return_value=mock_fit_function) mock_parm_1 = MagicMock() - mock_parm_1.unique_name = "mock_parm_1" + mock_parm_1.unique_name = 'mock_parm_1' mock_parm_1.value = 1000.0 mock_parm_2 = MagicMock() - mock_parm_2.unique_name = "mock_parm_2" + mock_parm_2.unique_name = 'mock_parm_2' mock_parm_2.value = 2000.0 # Then @@ -135,98 +135,92 @@ def test_make_model(self, minimizer: DFO) -> None: # Expect minimizer._generate_fit_function.assert_called_once_with() - assert all( - np.array([-0.01, -0.01]) == residuals_for_model(np.array([1111, 2222])) - ) + assert all(np.array([-0.01, -0.01]) == residuals_for_model(np.array([1111, 2222]))) assert all(mock_fit_function.call_args[0][0] == np.array([1, 2])) assert mock_fit_function.call_args[1] == { - "pmock_parm_1": 1111, - "pmock_parm_2": 2222, + 'pmock_parm_1': 1111, + 'pmock_parm_2': 2222, } def test_set_parameter_fit_result_no_stack_status(self, minimizer: DFO): # When minimizer._cached_pars = { - "a": MagicMock(), - "b": MagicMock(), + 'a': MagicMock(), + 'b': MagicMock(), } - minimizer._cached_pars["a"].value = "a" - minimizer._cached_pars["b"].value = "b" + minimizer._cached_pars['a'].value = 'a' + minimizer._cached_pars['b'].value = 'b' mock_fit_result = MagicMock() mock_fit_result.x = [1.0, 2.0] - mock_fit_result.jacobian = "jacobian" - mock_fit_result.resid = "resid" + mock_fit_result.jacobian = 'jacobian' + mock_fit_result.resid = 'resid' - minimizer._error_from_jacobian = MagicMock( - return_value=np.array([[0.1, 0.0], [0.0, 0.2]]) - ) + minimizer._error_from_jacobian = MagicMock(return_value=np.array([[0.1, 0.0], [0.0, 0.2]])) # Then minimizer._set_parameter_fit_result(mock_fit_result, False) # Expect - assert minimizer._cached_pars["a"].value == 1.0 - assert minimizer._cached_pars["a"].error == 0.1 - assert minimizer._cached_pars["b"].value == 2.0 - assert minimizer._cached_pars["b"].error == 0.2 - minimizer._error_from_jacobian.assert_called_once_with( - "jacobian", "resid", 0.95 - ) + assert minimizer._cached_pars['a'].value == 1.0 + assert minimizer._cached_pars['a'].error == 0.1 + assert minimizer._cached_pars['b'].value == 2.0 + assert minimizer._cached_pars['b'].error == 0.2 + minimizer._error_from_jacobian.assert_called_once_with('jacobian', 'resid', 0.95) def test_gen_fit_results(self, minimizer: DFO, monkeypatch): # When mock_domain_fit_results = MagicMock() mock_FitResults = MagicMock(return_value=mock_domain_fit_results) monkeypatch.setattr( - easyscience.fitting.minimizers.minimizer_dfo, "FitResults", mock_FitResults + easyscience.fitting.minimizers.minimizer_dfo, 'FitResults', mock_FitResults ) mock_fit_result = MagicMock() mock_fit_result.flag = False mock_cached_model = MagicMock() - mock_cached_model.x = "x" - mock_cached_model.y = "y" + mock_cached_model.x = 'x' + mock_cached_model.y = 'y' minimizer._cached_model = mock_cached_model mock_cached_par_1 = MagicMock() - mock_cached_par_1.value = "par_value_1" + mock_cached_par_1.value = 'par_value_1' mock_cached_par_2 = MagicMock() - mock_cached_par_2.value = "par_value_2" + mock_cached_par_2.value = 'par_value_2' minimizer._cached_pars = { - "par_1": mock_cached_par_1, - "par_2": mock_cached_par_2, + 'par_1': mock_cached_par_1, + 'par_2': mock_cached_par_2, } - minimizer._p_0 = "p_0" - minimizer.evaluate = MagicMock(return_value="evaluate") + minimizer._p_0 = 'p_0' + minimizer.evaluate = MagicMock(return_value='evaluate') # Then domain_fit_results = minimizer._gen_fit_results( - mock_fit_result, "weights", **{"kwargs_set_key": "kwargs_set_val"} + mock_fit_result, 'weights', **{'kwargs_set_key': 'kwargs_set_val'} ) # Expect assert domain_fit_results == mock_domain_fit_results - assert domain_fit_results.kwargs_set_key == "kwargs_set_val" + assert domain_fit_results.kwargs_set_key == 'kwargs_set_val' assert domain_fit_results.success == True - assert domain_fit_results.y_obs == "y" - assert domain_fit_results.x == "x" + assert domain_fit_results.y_obs == 'y' + assert domain_fit_results.x == 'x' assert domain_fit_results.p == { - "ppar_1": "par_value_1", - "ppar_2": "par_value_2", + 'ppar_1': 'par_value_1', + 'ppar_2': 'par_value_2', } - assert domain_fit_results.p0 == "p_0" - assert domain_fit_results.y_calc == "evaluate" - assert domain_fit_results.y_err == "weights" + assert domain_fit_results.p0 == 'p_0' + assert domain_fit_results.y_calc == 'evaluate' + assert domain_fit_results.y_err == 'weights' assert ( str(domain_fit_results.minimizer_engine) == "" ) assert domain_fit_results.fit_args is None minimizer.evaluate.assert_called_once_with( - "x", minimizer_parameters={"ppar_1": "par_value_1", "ppar_2": "par_value_2"} + 'x', minimizer_parameters={'ppar_1': 'par_value_1', 'ppar_2': 'par_value_2'} ) def test_dfo_fit(self, minimizer: DFO, monkeypatch): @@ -241,28 +235,26 @@ def test_dfo_fit(self, minimizer: DFO, monkeypatch): mock_parm_2.max = 20.0 pars = {1: mock_parm_1, 2: mock_parm_2} - kwargs = {"kwargs_set_key": "kwargs_set_val"} + kwargs = {'kwargs_set_key': 'kwargs_set_val'} mock_dfols = MagicMock() mock_results = MagicMock() - mock_results.msg = "Success" + mock_results.msg = 'Success' mock_dfols.solve = MagicMock(return_value=mock_results) - monkeypatch.setattr( - easyscience.fitting.minimizers.minimizer_dfo, "dfols", mock_dfols - ) + monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_dfo, 'dfols', mock_dfols) # Then - results = minimizer._dfo_fit(pars, "model", **kwargs) + results = minimizer._dfo_fit(pars, 'model', **kwargs) # Expect assert results == mock_results - assert mock_dfols.solve.call_args[0][0] == "model" + assert mock_dfols.solve.call_args[0][0] == 'model' assert all(mock_dfols.solve.call_args[0][1] == np.array([1.0, 2.0])) - assert all(mock_dfols.solve.call_args[1]["bounds"][0] == np.array([0.1, 0.2])) - assert all(mock_dfols.solve.call_args[1]["bounds"][1] == np.array([10.0, 20.0])) - assert mock_dfols.solve.call_args[1]["scaling_within_bounds"] is True - assert mock_dfols.solve.call_args[1]["kwargs_set_key"] == "kwargs_set_val" + assert all(mock_dfols.solve.call_args[1]['bounds'][0] == np.array([0.1, 0.2])) + assert all(mock_dfols.solve.call_args[1]['bounds'][1] == np.array([10.0, 20.0])) + assert mock_dfols.solve.call_args[1]['scaling_within_bounds'] is True + assert mock_dfols.solve.call_args[1]['kwargs_set_key'] == 'kwargs_set_val' def test_dfo_fit_no_scaling(self, minimizer: DFO, monkeypatch): # When @@ -276,46 +268,40 @@ def test_dfo_fit_no_scaling(self, minimizer: DFO, monkeypatch): mock_parm_2.max = 20.0 pars = {1: mock_parm_1, 2: mock_parm_2} - kwargs = {"kwargs_set_key": "kwargs_set_val"} + kwargs = {'kwargs_set_key': 'kwargs_set_val'} mock_dfols = MagicMock() mock_results = MagicMock() - mock_results.msg = "Success" + mock_results.msg = 'Success' mock_dfols.solve = MagicMock(return_value=mock_results) - monkeypatch.setattr( - easyscience.fitting.minimizers.minimizer_dfo, "dfols", mock_dfols - ) + monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_dfo, 'dfols', mock_dfols) # Then - results = minimizer._dfo_fit(pars, "model", **kwargs) + results = minimizer._dfo_fit(pars, 'model', **kwargs) # Expect assert results == mock_results - assert mock_dfols.solve.call_args[0][0] == "model" + assert mock_dfols.solve.call_args[0][0] == 'model' assert all(mock_dfols.solve.call_args[0][1] == np.array([1.0, 2.0])) - assert all( - mock_dfols.solve.call_args[1]["bounds"][0] == np.array([-np.inf, 0.2]) - ) - assert all(mock_dfols.solve.call_args[1]["bounds"][1] == np.array([10.0, 20.0])) - assert not "scaling_within_bounds" in list(mock_dfols.solve.call_args[1].keys()) - assert "kwargs_set_key" in list(mock_dfols.solve.call_args[1].keys()) - assert mock_dfols.solve.call_args[1]["kwargs_set_key"] == "kwargs_set_val" + assert all(mock_dfols.solve.call_args[1]['bounds'][0] == np.array([-np.inf, 0.2])) + assert all(mock_dfols.solve.call_args[1]['bounds'][1] == np.array([10.0, 20.0])) + assert 'scaling_within_bounds' not in list(mock_dfols.solve.call_args[1].keys()) + assert 'kwargs_set_key' in list(mock_dfols.solve.call_args[1].keys()) + assert mock_dfols.solve.call_args[1]['kwargs_set_key'] == 'kwargs_set_val' def test_dfo_fit_exception(self, minimizer: DFO, monkeypatch): # When pars = {1: MagicMock(Parameter)} - kwargs = {"kwargs_set_key": "kwargs_set_val"} + kwargs = {'kwargs_set_key': 'kwargs_set_val'} mock_dfols = MagicMock() mock_results = MagicMock() - mock_results.msg = "Failed" + mock_results.msg = 'Failed' mock_dfols.solve = MagicMock(return_value=mock_results) - monkeypatch.setattr( - easyscience.fitting.minimizers.minimizer_dfo, "dfols", mock_dfols - ) + monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_dfo, 'dfols', mock_dfols) # Then Expect with pytest.raises(FitError): - minimizer._dfo_fit(pars, "model", **kwargs) + minimizer._dfo_fit(pars, 'model', **kwargs) diff --git a/tests/unit_tests/fitting/minimizers/test_minimizer_lmfit.py b/tests/unit/fitting/minimizers/test_minimizer_lmfit.py similarity index 75% rename from tests/unit_tests/fitting/minimizers/test_minimizer_lmfit.py rename to tests/unit/fitting/minimizers/test_minimizer_lmfit.py index 1185082f..ac280873 100644 --- a/tests/unit_tests/fitting/minimizers/test_minimizer_lmfit.py +++ b/tests/unit/fitting/minimizers/test_minimizer_lmfit.py @@ -1,22 +1,25 @@ -import pytest +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause from unittest.mock import MagicMock +import numpy as np +import pytest +from lmfit import Parameter as LMParameter + import easyscience.fitting.minimizers.minimizer_lmfit -from easyscience.fitting.minimizers.minimizer_lmfit import LMFit from easyscience import Parameter -from lmfit import Parameter as LMParameter +from easyscience.fitting.minimizers.minimizer_lmfit import LMFit from easyscience.fitting.minimizers.utils import FitError -import numpy as np -class TestLMFit(): +class TestLMFit: @pytest.fixture def minimizer(self) -> LMFit: minimizer = LMFit( obj='obj', - fit_function='fit_function', - minimizer_enum=MagicMock(package='lm', method='leastsq') + fit_function='fit_function', + minimizer_enum=MagicMock(package='lm', method='leastsq'), ) return minimizer @@ -27,11 +30,22 @@ def test_init_exception(self) -> None: with pytest.raises(FitError): LMFit( obj='obj', - fit_function='fit_function', - minimizer_enum=MagicMock(package='dfo', method='not_leastsq') + fit_function='fit_function', + minimizer_enum=MagicMock(package='dfo', method='not_leastsq'), ) - @pytest.mark.parametrize("weights", [np.array([1, 2, 3, 4]), np.array([[1, 2, 3], [4, 5, 6]]), np.repeat(np.nan,3), np.zeros(3), np.repeat(np.inf,3), -np.ones(3)], ids=["wrong_length", "multidimensional", "NaNs", "zeros", "Infs", "negative"]) + @pytest.mark.parametrize( + 'weights', + [ + np.array([1, 2, 3, 4]), + np.array([[1, 2, 3], [4, 5, 6]]), + np.repeat(np.nan, 3), + np.zeros(3), + np.repeat(np.inf, 3), + -np.ones(3), + ], + ids=['wrong_length', 'multidimensional', 'NaNs', 'zeros', 'Infs', 'negative'], + ) def test_fit_weight_exceptions(self, minimizer: LMFit, weights) -> None: # When Then Expect with pytest.raises(ValueError): @@ -41,7 +55,9 @@ def test_make_model(self, minimizer: LMFit, monkeypatch) -> None: # When mock_lm_model = MagicMock() mock_LMModel = MagicMock(return_value=mock_lm_model) - monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_lmfit, "LMModel", mock_LMModel) + monkeypatch.setattr( + easyscience.fitting.minimizers.minimizer_lmfit, 'LMModel', mock_LMModel + ) minimizer._generate_fit_function = MagicMock(return_value='model') mock_parm_1 = MagicMock(LMParameter) mock_parm_1.value = 1.0 @@ -55,10 +71,12 @@ def test_make_model(self, minimizer: LMFit, monkeypatch) -> None: # Then model = minimizer._make_model(pars=pars) - + # Expect minimizer._generate_fit_function.assert_called_once_with() - mock_LMModel.assert_called_once_with('model', independent_vars=['x'], param_names=['pkey_1', 'pkey_2']) + mock_LMModel.assert_called_once_with( + 'model', independent_vars=['x'], param_names=['pkey_1', 'pkey_2'] + ) mock_lm_model.set_param_hint.assert_called_with('pkey_2', value=2.0, min=-20.0, max=20.0) assert mock_lm_model.set_param_hint.call_count == 2 assert model == mock_lm_model @@ -67,7 +85,9 @@ def test_make_model_no_pars(self, minimizer: LMFit, monkeypatch) -> None: # When mock_lm_model = MagicMock() mock_LMModel = MagicMock(return_value=mock_lm_model) - monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_lmfit, "LMModel", mock_LMModel) + monkeypatch.setattr( + easyscience.fitting.minimizers.minimizer_lmfit, 'LMModel', mock_LMModel + ) minimizer._generate_fit_function = MagicMock(return_value='model') mock_parm_1 = MagicMock(Parameter) mock_parm_1.value = 1.0 @@ -81,10 +101,12 @@ def test_make_model_no_pars(self, minimizer: LMFit, monkeypatch) -> None: # Then model = minimizer._make_model() - + # Expect minimizer._generate_fit_function.assert_called_once_with() - mock_LMModel.assert_called_once_with('model', independent_vars=['x'], param_names=['pkey_1', 'pkey_2']) + mock_LMModel.assert_called_once_with( + 'model', independent_vars=['x'], param_names=['pkey_1', 'pkey_2'] + ) mock_lm_model.set_param_hint.assert_called_with('pkey_2', value=2.0, min=-20.0, max=20.0) assert mock_lm_model.set_param_hint.call_count == 2 assert model == mock_lm_model @@ -92,6 +114,7 @@ def test_make_model_no_pars(self, minimizer: LMFit, monkeypatch) -> None: def test_fit(self, minimizer: LMFit) -> None: # When from easyscience import global_object + global_object.stack.enabled = False mock_model = MagicMock() @@ -105,7 +128,9 @@ def test_fit(self, minimizer: LMFit) -> None: # Expect assert result == 'gen_fit_results' - mock_model.fit.assert_called_once_with(2.0, x=1.0, weights=1, max_nfev=None, fit_kws={}, method='leastsq') + mock_model.fit.assert_called_once_with( + 2.0, x=1.0, weights=1, max_nfev=None, fit_kws={}, method='leastsq' + ) minimizer._make_model.assert_called_once_with() minimizer._set_parameter_fit_result.assert_called_once_with('fit', False) minimizer._gen_fit_results.assert_called_once_with('fit') @@ -122,7 +147,9 @@ def test_fit_model(self, minimizer: LMFit) -> None: minimizer.fit(x=1.0, y=2.0, weights=1, model=mock_model) # Expect - mock_model.fit.assert_called_once_with(2.0, x=1.0, weights=1, max_nfev=None, fit_kws={}, method='leastsq') + mock_model.fit.assert_called_once_with( + 2.0, x=1.0, weights=1, max_nfev=None, fit_kws={}, method='leastsq' + ) minimizer._make_model.assert_not_called() def test_fit_method(self, minimizer: LMFit) -> None: @@ -139,7 +166,9 @@ def test_fit_method(self, minimizer: LMFit) -> None: minimizer.fit(x=1.0, y=2.0, weights=1, method='method_passed') # Expect - mock_model.fit.assert_called_once_with(2.0, x=1.0, weights=1, max_nfev=None, fit_kws={}, method='method_passed') + mock_model.fit.assert_called_once_with( + 2.0, x=1.0, weights=1, max_nfev=None, fit_kws={}, method='method_passed' + ) minimizer.supported_methods.assert_called_once_with() def test_fit_kwargs(self, minimizer: LMFit) -> None: @@ -151,10 +180,24 @@ def test_fit_kwargs(self, minimizer: LMFit) -> None: minimizer._gen_fit_results = MagicMock(return_value='gen_fit_results') # Then - minimizer.fit(x=1.0, y=2.0, weights=1, minimizer_kwargs={'minimizer_key': 'minimizer_val'}, engine_kwargs={'engine_key': 'engine_val'}) + minimizer.fit( + x=1.0, + y=2.0, + weights=1, + minimizer_kwargs={'minimizer_key': 'minimizer_val'}, + engine_kwargs={'engine_key': 'engine_val'}, + ) # Expect - mock_model.fit.assert_called_once_with(2.0, x=1.0, weights=1, max_nfev=None, fit_kws={'minimizer_key': 'minimizer_val'}, method='leastsq', engine_key='engine_val') + mock_model.fit.assert_called_once_with( + 2.0, + x=1.0, + weights=1, + max_nfev=None, + fit_kws={'minimizer_key': 'minimizer_val'}, + method='leastsq', + engine_key='engine_val', + ) def test_fit_exception(self, minimizer: LMFit) -> None: # When @@ -169,14 +212,16 @@ def test_fit_exception(self, minimizer: LMFit) -> None: def test_convert_to_pars_obj(self, minimizer: LMFit, monkeypatch) -> None: # When minimizer._object = MagicMock() - minimizer._object.get_fit_parameters = MagicMock(return_value = ['parm_1', 'parm_2']) + minimizer._object.get_fit_parameters = MagicMock(return_value=['parm_1', 'parm_2']) minimizer.convert_to_par_object = MagicMock(return_value='convert_to_par_object') mock_lm_parameter = MagicMock() mock_lm_parameter.add_many = MagicMock(return_value='add_many') mock_LMParameters = MagicMock(return_value=mock_lm_parameter) - monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_lmfit, "LMParameters", mock_LMParameters) + monkeypatch.setattr( + easyscience.fitting.minimizers.minimizer_lmfit, 'LMParameters', mock_LMParameters + ) # Then pars = minimizer.convert_to_pars_obj() @@ -186,7 +231,10 @@ def test_convert_to_pars_obj(self, minimizer: LMFit, monkeypatch) -> None: assert minimizer.convert_to_par_object.call_count == 2 minimizer._object.get_fit_parameters.assert_called_once_with() minimizer.convert_to_par_object.assert_called_with('parm_2') - mock_lm_parameter.add_many.assert_called_once_with(['convert_to_par_object', 'convert_to_par_object']) + mock_lm_parameter.add_many.assert_called_once_with([ + 'convert_to_par_object', + 'convert_to_par_object', + ]) def test_convert_to_pars_obj_with_parameters(self, minimizer: LMFit, monkeypatch) -> None: # When @@ -195,7 +243,9 @@ def test_convert_to_pars_obj_with_parameters(self, minimizer: LMFit, monkeypatch mock_lm_parameter = MagicMock() mock_lm_parameter.add_many = MagicMock(return_value='add_many') mock_LMParameters = MagicMock(return_value=mock_lm_parameter) - monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_lmfit, "LMParameters", mock_LMParameters) + monkeypatch.setattr( + easyscience.fitting.minimizers.minimizer_lmfit, 'LMParameters', mock_LMParameters + ) # Then pars = minimizer.convert_to_pars_obj(['parm_1', 'parm_2']) @@ -204,13 +254,18 @@ def test_convert_to_pars_obj_with_parameters(self, minimizer: LMFit, monkeypatch assert pars == 'add_many' assert minimizer.convert_to_par_object.call_count == 2 minimizer.convert_to_par_object.assert_called_with('parm_2') - mock_lm_parameter.add_many.assert_called_once_with(['convert_to_par_object', 'convert_to_par_object']) + mock_lm_parameter.add_many.assert_called_once_with([ + 'convert_to_par_object', + 'convert_to_par_object', + ]) def test_convert_to_par_object(self, minimizer: LMFit, monkeypatch) -> None: # When mock_lm_parameter = MagicMock() mock_LMParameter = MagicMock(return_value=mock_lm_parameter) - monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_lmfit, "LMParameter", mock_LMParameter) + monkeypatch.setattr( + easyscience.fitting.minimizers.minimizer_lmfit, 'LMParameter', mock_LMParameter + ) mock_parm = MagicMock(Parameter) mock_parm.value = 1.0 @@ -224,7 +279,15 @@ def test_convert_to_par_object(self, minimizer: LMFit, monkeypatch) -> None: # Expect assert par == mock_lm_parameter - mock_LMParameter.assert_called_once_with('pkey_converted', value=1.0, vary=False, min=-10.0, max=10.0, expr=None, brute_step=None) + mock_LMParameter.assert_called_once_with( + 'pkey_converted', + value=1.0, + vary=False, + min=-10.0, + max=10.0, + expr=None, + brute_step=None, + ) def test_set_parameter_fit_result_no_stack_status(self, minimizer: LMFit) -> None: # When @@ -286,10 +349,12 @@ def test_gen_fit_results(self, minimizer: LMFit, monkeypatch) -> None: # When mock_domain_fit_results = MagicMock() mock_FitResults = MagicMock(return_value=mock_domain_fit_results) - monkeypatch.setattr(easyscience.fitting.minimizers.minimizer_lmfit, "FitResults", mock_FitResults) + monkeypatch.setattr( + easyscience.fitting.minimizers.minimizer_lmfit, 'FitResults', mock_FitResults + ) mock_fit_result = MagicMock() - mock_fit_result.success ='success' + mock_fit_result.success = 'success' mock_fit_result.data = 'data' mock_fit_result.userkws = {'x': 'x_val'} mock_fit_result.values = 'values' @@ -298,18 +363,22 @@ def test_gen_fit_results(self, minimizer: LMFit, monkeypatch) -> None: mock_fit_result.weights = 10 # Then - domain_fit_results = minimizer._gen_fit_results(mock_fit_result, **{'kwargs_set_key': 'kwargs_set_val'}) + domain_fit_results = minimizer._gen_fit_results( + mock_fit_result, **{'kwargs_set_key': 'kwargs_set_val'} + ) # Expect assert domain_fit_results == mock_domain_fit_results assert domain_fit_results.kwargs_set_key == 'kwargs_set_val' - assert domain_fit_results.success == 'success' + assert domain_fit_results.success == 'success' assert domain_fit_results.y_obs == 'data' assert domain_fit_results.x == 'x_val' assert domain_fit_results.p == 'values' assert domain_fit_results.p0 == 'init_values' assert domain_fit_results.y_calc == 'best_fit' assert domain_fit_results.y_err == 0.1 - assert str(domain_fit_results.minimizer_engine) == "" + assert ( + str(domain_fit_results.minimizer_engine) + == "" + ) assert domain_fit_results.fit_args is None - diff --git a/tests/unit_tests/fitting/test_fitter.py b/tests/unit/fitting/test_fitter.py similarity index 88% rename from tests/unit_tests/fitting/test_fitter.py rename to tests/unit/fitting/test_fitter.py index dede119c..73f5a12a 100644 --- a/tests/unit_tests/fitting/test_fitter.py +++ b/tests/unit/fitting/test_fitter.py @@ -1,13 +1,17 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from unittest.mock import MagicMock -import pytest import numpy as np +import pytest + import easyscience.fitting.fitter -from easyscience import Fitter from easyscience import AvailableMinimizers +from easyscience import Fitter -class TestFitter(): +class TestFitter: @pytest.fixture def fitter(self, monkeypatch): monkeypatch.setattr(Fitter, '_update_minimizer', MagicMock()) @@ -20,7 +24,7 @@ def test_constructor(self, fitter: Fitter): assert fitter._fit_object == self.mock_fit_object assert fitter._fit_function == self.mock_fit_function assert fitter._dependent_dims is None - assert fitter._enum_current_minimizer is None #== AvailableMinimizers.LMFit_leastsq + assert fitter._enum_current_minimizer is None # == AvailableMinimizers.LMFit_leastsq assert fitter._minimizer is None fitter._update_minimizer.assert_called_once_with(AvailableMinimizers.LMFit_leastsq) @@ -88,7 +92,7 @@ def test_create(self, fitter: Fitter, monkeypatch): # Expect mock_string_to_enum.assert_called_once_with('great-minimizer') fitter._update_minimizer.assert_called_once_with(10) - + def test_switch_minimizer(self, fitter: Fitter, monkeypatch): # When mock_minimizer = MagicMock() @@ -127,23 +131,32 @@ def test_available_minimizers(self, fitter: Fitter): # Then Expect assert minimizers == [ - 'LMFit', 'LMFit_leastsq', 'LMFit_powell', 'LMFit_cobyla', 'LMFit_differential_evolution', 'LMFit_scipy_least_squares', - 'Bumps', 'Bumps_simplex', 'Bumps_newton', 'Bumps_lm', - 'DFO', 'DFO_leastsq' + 'LMFit', + 'LMFit_leastsq', + 'LMFit_powell', + 'LMFit_cobyla', + 'LMFit_differential_evolution', + 'LMFit_scipy_least_squares', + 'Bumps', + 'Bumps_simplex', + 'Bumps_newton', + 'Bumps_lm', + 'DFO', + 'DFO_leastsq', ] def test_minimizer(self, fitter: Fitter): # When fitter._minimizer = 'minimizer' - # Then + # Then minimizer = fitter.minimizer # Expect assert minimizer == 'minimizer' def test_fit_function(self, fitter: Fitter): - # When Then + # When Then fit_function = fitter.fit_function # Expect @@ -161,7 +174,7 @@ def test_set_fit_function(self, fitter: Fitter): fitter._update_minimizer.assert_called_with('current_minimizer') def test_fit_object(self, fitter: Fitter): - # When Then + # When Then fit_object = fitter.fit_object # Expect @@ -180,7 +193,9 @@ def test_set_fit_object(self, fitter: Fitter): def test_fit(self, fitter: Fitter): # When - fitter._precompute_reshaping = MagicMock(return_value=('x_fit', 'x_new', 'y_new', 'weights', 'dims')) + fitter._precompute_reshaping = MagicMock( + return_value=('x_fit', 'x_new', 'y_new', 'weights', 'dims') + ) fitter._fit_function_wrapper = MagicMock(return_value='wrapped_fit_function') fitter._post_compute_reshaping = MagicMock(return_value='fit_result') fitter._minimizer = MagicMock() @@ -191,7 +206,7 @@ def test_fit(self, fitter: Fitter): # Expect fitter._precompute_reshaping.assert_called_once_with('x', 'y', 'weights', 'vectorized') - fitter._fit_function_wrapper.assert_called_once_with('x_new', flatten=True) + fitter._fit_function_wrapper.assert_called_once_with('x_new', flatten=True) fitter._post_compute_reshaping.assert_called_once_with('result', 'x', 'y') assert result == 'fit_result' assert fitter._dependent_dims == 'dims' @@ -200,8 +215,8 @@ def test_fit(self, fitter: Fitter): def test_post_compute_reshaping(self, fitter: Fitter): # When fit_result = MagicMock() - fit_result.y_calc = np.array([[10], [20], [30]]) - fit_result.y_err = np.array([[40], [50], [60]]) + fit_result.y_calc = np.array([[10], [20], [30]]) + fit_result.y_err = np.array([[40], [50], [60]]) x = np.array([1, 2, 3]) y = np.array([4, 5, 6]) @@ -210,10 +225,11 @@ def test_post_compute_reshaping(self, fitter: Fitter): # Expect assert np.array_equal(result.y_calc, np.array([10, 20, 30])) - assert np.array_equal(result.y_err, np.array([40, 50, 60])) + assert np.array_equal(result.y_err, np.array([40, 50, 60])) assert np.array_equal(result.x, x) assert np.array_equal(result.y_obs, y) + # TODO # def test_fit_function_wrapper() # def test_precompute_reshaping() diff --git a/tests/unit/global_object/__init__.py b/tests/unit/global_object/__init__.py new file mode 100644 index 00000000..b1990ec8 --- /dev/null +++ b/tests/unit/global_object/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + diff --git a/tests/unit_tests/global_object/test_entry_list_comprehensive.py b/tests/unit/global_object/test_entry_list_comprehensive.py similarity index 88% rename from tests/unit_tests/global_object/test_entry_list_comprehensive.py rename to tests/unit/global_object/test_entry_list_comprehensive.py index e8c038fe..7a15ba2f 100644 --- a/tests/unit_tests/global_object/test_entry_list_comprehensive.py +++ b/tests/unit/global_object/test_entry_list_comprehensive.py @@ -1,72 +1,71 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause -import pytest -import weakref from unittest.mock import MagicMock + from easyscience.global_object.map import _EntryList + class TestEntryListComprehensive: """Comprehensive tests for _EntryList class""" - + def test_inheritance(self): """Test that _EntryList properly inherits from list""" entry = _EntryList([1, 2, 3]) - + # Should have list functionality assert len(entry) == 3 assert entry[0] == 1 assert 2 in entry - + # Can append like a normal list entry.append(4) assert len(entry) == 4 - + def test_init_with_list_data(self): """Test initialization with existing list data""" data = ['a', 'b', 'c'] entry = _EntryList(data, my_type='created') - + assert len(entry) == 3 assert entry[0] == 'a' assert 'created' in entry.type - + def test_known_types_validation(self): """Test validation of known types""" entry = _EntryList() known_types = {'argument', 'created', 'created_internal', 'returned'} - + # Test all known types for known_type in known_types: entry.type = known_type assert known_type in entry.type - + # Test unknown type entry.type = 'unknown_type' assert 'unknown_type' not in entry.type - + def test_finalizer_attribute(self): """Test finalizer attribute handling""" entry = _EntryList() - + # Initially None assert entry.finalizer is None - + # Can set to any value mock_finalizer = MagicMock() entry.finalizer = mock_finalizer assert entry.finalizer is mock_finalizer - + def test_delitem_override(self): """Test __delitem__ override""" entry = _EntryList(['a', 'b', 'c']) - + # Should work like normal list deletion del entry[1] assert len(entry) == 2 assert entry == ['a', 'c'] - + def test_repr_variations(self): """Test various __repr__ scenarios""" # Empty type, no finalizer @@ -74,247 +73,248 @@ def test_repr_variations(self): repr_str = str(entry) assert 'Undefined' in repr_str assert 'Without' in repr_str - + # Single type, no finalizer entry.type = 'created' repr_str = str(entry) assert 'created' in repr_str assert 'Without' in repr_str - + # Multiple types, no finalizer entry.type = 'argument' repr_str = str(entry) assert 'created' in repr_str assert 'argument' in repr_str assert 'Without' in repr_str - + # With finalizer entry.finalizer = MagicMock() repr_str = str(entry) assert 'Without' not in repr_str - + def test_type_setter_edge_cases(self): """Test edge cases for type setter""" entry = _EntryList() - + # Setting None should not crash entry.type = None assert None not in entry.type - + # Setting empty string - entry.type = "" - assert "" not in entry.type - + entry.type = '' + assert '' not in entry.type + # Setting numeric value entry.type = 123 assert 123 not in entry.type - + def test_remove_type_edge_cases(self): """Test edge cases for remove_type""" entry = _EntryList() entry.type = 'created' entry.type = 'argument' - + # Remove type that exists entry.remove_type('created') assert 'created' not in entry.type assert 'argument' in entry.type - + # Remove type that doesn't exist entry.remove_type('returned') # Not in list assert 'argument' in entry.type # Should be unchanged - + # Remove unknown type entry.remove_type('unknown') assert 'argument' in entry.type # Should be unchanged - + # Remove None entry.remove_type(None) assert 'argument' in entry.type # Should be unchanged - + def test_reset_type_variations(self): """Test reset_type with various inputs""" entry = _EntryList() entry.type = 'created' entry.type = 'argument' - + # Reset with valid type entry.reset_type('returned') assert entry.type == ['returned'] - + # Reset with invalid type entry.type = 'created' # Add something first entry.reset_type('invalid') assert entry.type == [] # Should be empty since invalid - + # Reset with None entry.type = 'created' entry.reset_type(None) assert entry.type == [] - + def test_boolean_properties_combinations(self): """Test boolean properties with multiple types""" entry = _EntryList() - + # Add multiple types entry.type = 'created' entry.type = 'argument' entry.type = 'returned' - + # All should be true assert entry.is_created assert entry.is_argument assert entry.is_returned assert not entry.is_created_internal # Not added - + # Remove one entry.remove_type('argument') assert entry.is_created assert not entry.is_argument assert entry.is_returned - + def test_list_functionality_preserved(self): """Test that list functionality is preserved""" entry = _EntryList() - + # Basic list operations entry.append('a') entry.append('b') entry.insert(1, 'x') assert entry == ['a', 'x', 'b'] - + # List methods assert entry.index('x') == 1 assert entry.count('a') == 1 - + # Slicing subset = entry[1:] assert subset == ['x', 'b'] - + # Iteration items = [item for item in entry] assert items == ['a', 'x', 'b'] - + def test_type_persistence_during_list_operations(self): """Test that type information persists during list operations""" entry = _EntryList(my_type='created') entry.type = 'argument' - + # Perform list operations entry.append('item1') entry.extend(['item2', 'item3']) entry.sort() - + # Type information should be preserved assert entry.is_created assert entry.is_argument - + def test_equality_with_regular_list(self): """Test equality comparison with regular list""" entry = _EntryList(['a', 'b', 'c']) regular_list = ['a', 'b', 'c'] - + # Should be equal in content assert entry == regular_list assert regular_list == entry - + # But not the same type assert type(entry) != type(regular_list) assert isinstance(entry, _EntryList) assert isinstance(entry, list) - + def test_copy_behavior(self): """Test copying behavior""" import copy - + entry = _EntryList(['a', 'b'], my_type='created') entry.finalizer = MagicMock() - + # Shallow copy shallow_copy = copy.copy(entry) assert shallow_copy == entry assert shallow_copy.type == entry.type assert shallow_copy.finalizer is entry.finalizer - + # Deep copy deep_copy = copy.deepcopy(entry) assert deep_copy == entry assert deep_copy.type == entry.type # Finalizer might be different in deep copy - + def test_memory_efficiency(self): """Test that _EntryList doesn't consume excessive memory""" # Create many entries entries = [] for i in range(1000): - entry = _EntryList([f"item_{i}"], my_type='created') + entry = _EntryList([f'item_{i}'], my_type='created') entries.append(entry) - + # Should not raise memory errors assert len(entries) == 1000 assert all(entry.is_created for entry in entries) - + def test_thread_safety_simulation(self): """Test basic thread safety aspects (simulation)""" import threading import time - + entry = _EntryList() results = [] - + def add_type(type_name, delay=0.001): time.sleep(delay) entry.type = type_name results.append(type_name) - + # Simulate concurrent access threads = [] for i, type_name in enumerate(['created', 'argument', 'returned']): thread = threading.Thread(target=add_type, args=(type_name,)) threads.append(thread) - + for thread in threads: thread.start() - + for thread in threads: thread.join() - + # All types should be added (order might vary) assert len(set(entry.type)) == 3 assert all(t in entry.type for t in ['created', 'argument', 'returned']) - + def test_pickle_serialization(self): """Test pickle serialization support""" import pickle - + entry = _EntryList(['a', 'b', 'c'], my_type='created') entry.type = 'argument' - + # Serialize pickled = pickle.dumps(entry) - + # Deserialize unpickled = pickle.loads(pickled) - + # Should preserve data and types assert unpickled == entry assert unpickled.type == entry.type assert unpickled.is_created assert unpickled.is_argument - + def test_subclassing(self): """Test that _EntryList can be subclassed""" + class CustomEntryList(_EntryList): def __init__(self, *args, custom_attr=None, **kwargs): super().__init__(*args, **kwargs) self.custom_attr = custom_attr - + def custom_method(self): - return f"Custom: {len(self)} items" - - custom = CustomEntryList(['x', 'y'], my_type='created', custom_attr="test") - - assert custom.custom_attr == "test" - assert custom.custom_method() == "Custom: 2 items" + return f'Custom: {len(self)} items' + + custom = CustomEntryList(['x', 'y'], my_type='created', custom_attr='test') + + assert custom.custom_attr == 'test' + assert custom.custom_method() == 'Custom: 2 items' assert custom.is_created - assert len(custom) == 2 \ No newline at end of file + assert len(custom) == 2 diff --git a/tests/unit_tests/global_object/test_global_object.py b/tests/unit/global_object/test_global_object.py similarity index 64% rename from tests/unit_tests/global_object/test_global_object.py rename to tests/unit/global_object/test_global_object.py index 96cc4888..719fee5a 100644 --- a/tests/unit_tests/global_object/test_global_object.py +++ b/tests/unit/global_object/test_global_object.py @@ -1,9 +1,13 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import pytest -import easyscience + +from easyscience import Parameter +from easyscience import global_object from easyscience.global_object.global_object import GlobalObject from easyscience.variable import DescriptorBool -from easyscience import Parameter, ObjBase, global_object -from unittest.mock import patch, MagicMock + class TestGlobalObject: def test_init(self): @@ -11,7 +15,7 @@ def test_init(self): global_object = GlobalObject() # Expect - assert global_object.log == GlobalObject().log + assert global_object.log == GlobalObject().log assert global_object.map == GlobalObject().map assert global_object.stack == GlobalObject().stack assert global_object.debug == GlobalObject().debug @@ -19,24 +23,30 @@ def test_init(self): def test_generate_unique_name(self): # When Then global_object = GlobalObject() - name = global_object.generate_unique_name("name_prefix") + name = global_object.generate_unique_name('name_prefix') # Expect - assert name == "name_prefix_0" + assert name == 'name_prefix_0' def test_generate_unique_name_already_taken(self): # When global_object = GlobalObject() # Block the other_name_prefix_2 name - keep_due_toweakref_1 = DescriptorBool(name="test", value=True, unique_name="other_name_prefix_2") - keep_due_toweakref_2 = DescriptorBool(name="test", value=True, unique_name="other_name_prefix_a_3") - keep_due_toweakref_3 = DescriptorBool(name="test", value=True, unique_name="almost_other_name_prefix_3") + keep_due_toweakref_1 = DescriptorBool( + name='test', value=True, unique_name='other_name_prefix_2' + ) + keep_due_toweakref_2 = DescriptorBool( + name='test', value=True, unique_name='other_name_prefix_a_3' + ) + keep_due_toweakref_3 = DescriptorBool( + name='test', value=True, unique_name='almost_other_name_prefix_3' + ) - # Then - name = global_object.generate_unique_name("other_name_prefix") + # Then + name = global_object.generate_unique_name('other_name_prefix') # Expect - assert name == "other_name_prefix_3" + assert name == 'other_name_prefix_3' @pytest.fixture def clear_global_map(self): @@ -50,7 +60,7 @@ def test_singleton_behavior(self): # When obj1 = GlobalObject() obj2 = GlobalObject() - + # Then assert obj1 is obj2 assert id(obj1) == id(obj2) @@ -61,23 +71,24 @@ def test_instantiate_stack(self, clear_global_map): """Test stack instantiation""" # Given global_obj = GlobalObject() - + # When global_obj.instantiate_stack() - + # Then assert global_obj.stack is not None from easyscience.global_object.undo_redo import UndoStack + assert isinstance(global_obj.stack, UndoStack) def test_debug_property(self): """Test debug property access""" # Given global_obj = GlobalObject() - + # When/Then assert global_obj.debug is False # Default value - + # Test that it's the same across instances global_obj2 = GlobalObject() assert global_obj.debug is global_obj2.debug @@ -86,70 +97,70 @@ def test_generate_unique_name_empty_map(self, clear_global_map): """Test unique name generation with empty map""" # Given global_obj = GlobalObject() - + # When - name = global_obj.generate_unique_name("test") - + name = global_obj.generate_unique_name('test') + # Then - assert name == "test_0" + assert name == 'test_0' def test_generate_unique_name_with_gaps(self, clear_global_map): """Test unique name generation with gaps in numbering""" # Given global_obj = GlobalObject() # Create objects with non-sequential names - keep1 = DescriptorBool(name="test", value=True, unique_name="prefix_0") - keep2 = DescriptorBool(name="test", value=True, unique_name="prefix_2") - keep3 = DescriptorBool(name="test", value=True, unique_name="prefix_5") - + keep1 = DescriptorBool(name='test', value=True, unique_name='prefix_0') + keep2 = DescriptorBool(name='test', value=True, unique_name='prefix_2') + keep3 = DescriptorBool(name='test', value=True, unique_name='prefix_5') + # When - name = global_obj.generate_unique_name("prefix") - + name = global_obj.generate_unique_name('prefix') + # Then - Should pick the highest + 1 - assert name == "prefix_6" + assert name == 'prefix_6' def test_generate_unique_name_non_numeric_suffix(self, clear_global_map): """Test that non-numeric suffixes are ignored""" # Given global_obj = GlobalObject() - keep1 = DescriptorBool(name="test", value=True, unique_name="prefix_abc") - keep2 = DescriptorBool(name="test", value=True, unique_name="prefix_1") - + keep1 = DescriptorBool(name='test', value=True, unique_name='prefix_abc') + keep2 = DescriptorBool(name='test', value=True, unique_name='prefix_1') + # When - name = global_obj.generate_unique_name("prefix") - + name = global_obj.generate_unique_name('prefix') + # Then - assert name == "prefix_2" + assert name == 'prefix_2' def test_generate_unique_name_similar_prefixes(self, clear_global_map): """Test that similar but different prefixes don't interfere""" # Given global_obj = GlobalObject() - keep1 = DescriptorBool(name="test", value=True, unique_name="test_param_5") - keep2 = DescriptorBool(name="test", value=True, unique_name="test_parameter_10") - + keep1 = DescriptorBool(name='test', value=True, unique_name='test_param_5') + keep2 = DescriptorBool(name='test', value=True, unique_name='test_parameter_10') + # When - name1 = global_obj.generate_unique_name("test_param") - name2 = global_obj.generate_unique_name("test_parameter") - + name1 = global_obj.generate_unique_name('test_param') + name2 = global_obj.generate_unique_name('test_parameter') + # Then - assert name1 == "test_param_6" - assert name2 == "test_parameter_11" + assert name1 == 'test_param_6' + assert name2 == 'test_parameter_11' def test_integration_with_parameter_creation(self, clear_global_map): """Test GlobalObject integration with Parameter creation""" # Given global_obj = GlobalObject() - + # When - param1 = Parameter(name="test1", value=1.0) - param2 = Parameter(name="test2", value=2.0) - + param1 = Parameter(name='test1', value=1.0) + param2 = Parameter(name='test2', value=2.0) + # Then assert len(global_obj.map.vertices()) == 2 assert param1.unique_name in global_obj.map.vertices() assert param2.unique_name in global_obj.map.vertices() - + # Test retrieval retrieved1 = global_obj.map.get_item_by_key(param1.unique_name) assert retrieved1 is param1 @@ -158,8 +169,9 @@ def test_script_manager_access(self): """Test that script manager is accessible""" # Given global_obj = GlobalObject() - + # Then assert hasattr(global_obj, 'script') from easyscience.global_object.hugger.hugger import ScriptManager + assert isinstance(global_obj.script, ScriptManager) diff --git a/tests/unit_tests/global_object/test_integration_comprehensive.py b/tests/unit/global_object/test_integration_comprehensive.py similarity index 76% rename from tests/unit_tests/global_object/test_integration_comprehensive.py rename to tests/unit/global_object/test_integration_comprehensive.py index 1ea9f584..61268954 100644 --- a/tests/unit_tests/global_object/test_integration_comprehensive.py +++ b/tests/unit/global_object/test_integration_comprehensive.py @@ -1,21 +1,21 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause -import pytest import gc -import weakref -from unittest.mock import MagicMock, patch +from unittest.mock import patch + +import pytest -from easyscience import Parameter, ObjBase, global_object +from easyscience import ObjBase +from easyscience import Parameter +from easyscience import global_object from easyscience.global_object.global_object import GlobalObject -from easyscience.global_object.map import Map, _EntryList -from easyscience.global_object.undo_redo import UndoStack -from easyscience.variable import DescriptorBool, DescriptorNumber +from easyscience.variable import DescriptorBool + class TestGlobalObjectIntegration: """Integration tests for GlobalObject ecosystem""" - + @pytest.fixture def clear_all(self): """Clear everything before and after each test""" @@ -26,44 +26,44 @@ def clear_all(self): global_object.map._clear() if global_object.stack: global_object.stack.clear() - + def test_parameter_lifecycle_integration(self, clear_all): """Test complete parameter lifecycle with global object integration""" # Given global_obj = GlobalObject() - + # When - Create parameter - param = Parameter(name="test_param", value=10.0, unit="m") - + param = Parameter(name='test_param', value=10.0, unit='m') + # Then - Should be registered in global map assert global_obj.map.is_known(param) assert param.unique_name in global_obj.map.vertices() assert 'created' in global_obj.map.find_type(param) - + # When - Modify parameter with undo/redo enabled if not global_obj.stack: global_obj.instantiate_stack() global_obj.stack.enabled = True - + original_value = param.value param.value = 20.0 - + # Then - Should be able to undo/redo assert param.value == 20.0 assert global_obj.stack.canUndo() - + global_obj.stack.undo() assert param.value == original_value - + global_obj.stack.redo() assert param.value == 20.0 - + # When - Delete parameter param_name = param.unique_name original_count = len(global_obj.map.vertices()) del param gc.collect() - + # Then - Should be removed from global map (via weak references) # Note: garbage collection timing can vary, so we check count decrease # or explicit cleanup @@ -72,130 +72,131 @@ def test_parameter_lifecycle_integration(self, clear_all): # If still present, manually clean up for test consistency global_obj.map.prune(param_name) assert param_name not in global_obj.map.vertices() - + def test_objbase_parameter_relationship(self, clear_all): """Test ObjBase containing parameters integration""" # Given global_obj = GlobalObject() - - param1 = Parameter(name="length", value=10.0, unit="m") - param2 = Parameter(name="width", value=5.0, unit="m") - + + param1 = Parameter(name='length', value=10.0, unit='m') + param2 = Parameter(name='width', value=5.0, unit='m') + # When - Create ObjBase with parameters - obj = ObjBase(name="rectangle", length=param1, width=param2) - + obj = ObjBase(name='rectangle', length=param1, width=param2) + # Then - All should be in global map assert global_obj.map.is_known(obj) assert global_obj.map.is_known(param1) assert global_obj.map.is_known(param2) - + # Check relationships in map obj_edges = global_obj.map.get_edges(obj) assert param1.unique_name in obj_edges assert param2.unique_name in obj_edges - + # When - Modify through ObjBase if not global_obj.stack: global_obj.instantiate_stack() global_obj.stack.enabled = True - + obj.length.value = 15.0 - + # Then - Should be able to undo assert global_obj.stack.canUndo() global_obj.stack.undo() assert obj.length.value == 10.0 - + def test_unique_name_generation_integration(self, clear_all): """Test unique name generation across different object types""" # Given global_obj = GlobalObject() - + # When - Create multiple objects of same type params = [] for i in range(5): - param = Parameter(name=f"param_{i}", value=float(i)) + param = Parameter(name=f'param_{i}', value=float(i)) params.append(param) - + # Then - Should have unique names unique_names = [p.unique_name for p in params] assert len(set(unique_names)) == 5 # All unique - + # Names should follow pattern for i, name in enumerate(unique_names): - assert name == f"Parameter_{i}" - + assert name == f'Parameter_{i}' + # When - Create mixed object types - obj = ObjBase(name="test_obj") - desc = DescriptorBool(name="test_desc", value=True) - + obj = ObjBase(name='test_obj') + desc = DescriptorBool(name='test_desc', value=True) + # Then - Should not interfere with each other's naming - assert obj.unique_name == "ObjBase_0" - assert desc.unique_name == "DescriptorBool_0" - + assert obj.unique_name == 'ObjBase_0' + assert desc.unique_name == 'DescriptorBool_0' + def test_map_vertex_type_management(self, clear_all): """Test comprehensive vertex type management""" # Given global_obj = GlobalObject() - param = Parameter(name="test", value=1.0) - + param = Parameter(name='test', value=1.0) + # When - Check initial type initial_types = global_obj.map.find_type(param) assert 'created' in initial_types - + # When - Change type global_obj.map.change_type(param, 'argument') updated_types = global_obj.map.find_type(param) assert 'created' in updated_types assert 'argument' in updated_types - + # When - Reset type global_obj.map.reset_type(param, 'returned') final_types = global_obj.map.find_type(param) assert final_types == ['returned'] - + # When - Filter by type returned_objs = global_obj.map.returned_objs assert param.unique_name in returned_objs - + created_objs = global_obj.map.created_objs assert param.unique_name not in created_objs - @pytest.mark.skip(reason="Weak reference timing can be inconsistent in tests") + + @pytest.mark.skip(reason='Weak reference timing can be inconsistent in tests') def test_weak_reference_cleanup_integration(self, clear_all): """Test that weak references properly clean up the map""" # Given global_obj = GlobalObject() - + # When - Create objects - param1 = Parameter(name="temp1", value=1.0) - param2 = Parameter(name="temp2", value=2.0) - obj = ObjBase(name="temp_obj", param1=param1, param2=param2) - + param1 = Parameter(name='temp1', value=1.0) + param2 = Parameter(name='temp2', value=2.0) + obj = ObjBase(name='temp_obj', param1=param1, param2=param2) + param1_name = param1.unique_name param2_name = param2.unique_name obj_name = obj.unique_name - + # Then - All should be present assert global_obj.map.is_known(param1) assert global_obj.map.is_known(param2) assert global_obj.map.is_known(obj) - + # When - Delete objects del param1 gc.collect() - + # Then - param1 should be removed assert param1_name not in global_obj.map.vertices() assert param2_name in global_obj.map.vertices() assert obj_name in global_obj.map.vertices() - + # When - Delete remaining objects del param2, obj gc.collect() - + # Then - Map should be empty assert len(global_obj.map.vertices()) == 0 - + def test_complex_undo_redo_scenario(self, clear_all): """Test complex undo/redo scenario with multiple objects""" # Given @@ -203,259 +204,253 @@ def test_complex_undo_redo_scenario(self, clear_all): if not global_obj.stack: global_obj.instantiate_stack() global_obj.stack.enabled = True - + # Create a complex object structure - length = Parameter(name="length", value=10.0, unit="m") - width = Parameter(name="width", value=5.0, unit="m") - height = Parameter(name="height", value=3.0, unit="m") - - box = ObjBase(name="box", length=length, width=width, height=height) - + length = Parameter(name='length', value=10.0, unit='m') + width = Parameter(name='width', value=5.0, unit='m') + height = Parameter(name='height', value=3.0, unit='m') + + box = ObjBase(name='box', length=length, width=width, height=height) + # When - Perform multiple operations in a macro - global_obj.stack.beginMacro("Resize box") - + global_obj.stack.beginMacro('Resize box') + length.value = 15.0 width.value = 7.0 height.value = 4.0 - + global_obj.stack.endMacro() - + # Then - All changes should be applied assert box.length.value == 15.0 assert box.width.value == 7.0 assert box.height.value == 4.0 - + # When - Undo macro assert global_obj.stack.canUndo() - assert global_obj.stack.undoText() == "Resize box" - + assert global_obj.stack.undoText() == 'Resize box' + global_obj.stack.undo() - + # Then - All changes should be reverted assert box.length.value == 10.0 assert box.width.value == 5.0 assert box.height.value == 3.0 - + # When - Redo macro assert global_obj.stack.canRedo() global_obj.stack.redo() - + # Then - All changes should be reapplied assert box.length.value == 15.0 assert box.width.value == 7.0 assert box.height.value == 4.0 - + def test_map_path_finding_integration(self, clear_all): """Test map path finding with real object relationships""" # Given global_obj = GlobalObject() - + # Create a hierarchy: container -> sub_container -> parameter - param = Parameter(name="value", value=42.0) - sub_container = ObjBase(name="sub", value=param) - main_container = ObjBase(name="main", sub=sub_container) - + param = Parameter(name='value', value=42.0) + sub_container = ObjBase(name='sub', value=param) + main_container = ObjBase(name='main', sub=sub_container) + # When - Find path from main to parameter - path = global_obj.map.find_path( - main_container.unique_name, - param.unique_name - ) - + path = global_obj.map.find_path(main_container.unique_name, param.unique_name) + # Then - Should find the path through the hierarchy assert len(path) >= 2 assert path[0] == main_container.unique_name assert path[-1] == param.unique_name - + # When - Find reverse path - reverse_path = global_obj.map.reverse_route( - param.unique_name, - main_container.unique_name - ) - + reverse_path = global_obj.map.reverse_route(param.unique_name, main_container.unique_name) + # Then - Should be the reverse assert reverse_path[0] == param.unique_name assert reverse_path[-1] == main_container.unique_name - + def test_map_connectivity_with_isolated_objects(self, clear_all): """Test map connectivity detection""" # Given global_obj = GlobalObject() - + # When - Create connected objects - param1 = Parameter(name="connected1", value=1.0) - param2 = Parameter(name="connected2", value=2.0) - container = ObjBase(name="container", p1=param1, p2=param2) - + param1 = Parameter(name='connected1', value=1.0) + param2 = Parameter(name='connected2', value=2.0) + container = ObjBase(name='container', p1=param1, p2=param2) + # Then - Map should be connected # TODO: Depending on implementation, connectivity might vary # assert global_obj.map.is_connected() - + # When - Create isolated object - isolated = Parameter(name="isolated", value=99.0) + isolated = Parameter(name='isolated', value=99.0) # Remove its automatic connection by clearing edges # (In real usage, isolated objects would be rare) - + # Then - Map might still be connected depending on implementation # This tests the connectivity algorithm connectivity = global_obj.map.is_connected() assert isinstance(connectivity, bool) - + def test_error_handling_integration(self, clear_all): """Test error handling across the global object system""" # Given global_obj = GlobalObject() - + # When - Try to get non-existent object - with pytest.raises(ValueError, match="Item not in map"): - global_obj.map.get_item_by_key("non_existent") - + with pytest.raises(ValueError, match='Item not in map'): + global_obj.map.get_item_by_key('non_existent') + # When - Try to add object with duplicate name - param1 = Parameter(name="test", value=1.0) + param1 = Parameter(name='test', value=1.0) param1_name = param1.unique_name - + # Create another with same unique name (should fail in add_vertex) - with pytest.raises(ValueError, match="already exists"): + with pytest.raises(ValueError, match='already exists'): # This simulates what would happen if we tried to add duplicate global_obj.map.add_vertex(param1) # param1 already added during creation - + def test_memory_pressure_simulation(self, clear_all): """Test system behavior under memory pressure""" # Given global_obj = GlobalObject() - + # When - Create many objects objects = [] for i in range(100): - param = Parameter(name=f"param_{i}", value=float(i)) - obj = ObjBase(name=f"obj_{i}", param=param) + param = Parameter(name=f'param_{i}', value=float(i)) + obj = ObjBase(name=f'obj_{i}', param=param) objects.append((param, obj)) - + initial_vertex_count = len(global_obj.map.vertices()) assert initial_vertex_count == 200 # 100 params + 100 objs - + # When - Delete half the objects objects_to_delete = [objects[i] for i in range(0, 100, 2)] for item in objects_to_delete: objects.remove(item) del item - + # Force garbage collection gc.collect() - + # Then - Map should have fewer vertices current_vertex_count = len(global_obj.map.vertices()) assert current_vertex_count <= initial_vertex_count - + # When - Delete all remaining objects del objects gc.collect() - + # Then - Map should be mostly empty (might have some remaining references) final_vertex_count = len(global_obj.map.vertices()) assert final_vertex_count < initial_vertex_count - + def test_serialization_integration_with_global_state(self, clear_all): """Test serialization integration with global state management""" # Given global_obj = GlobalObject() - + # Create objects - param = Parameter(name="test_param", value=123.45, unit="kg") - obj = ObjBase(name="test_obj", param=param) - + param = Parameter(name='test_param', value=123.45, unit='kg') + obj = ObjBase(name='test_obj', param=param) + original_vertex_count = len(global_obj.map.vertices()) - + # When - Serialize objects param_dict = param.as_dict() obj_dict = obj.as_dict() - + # Clear global state global_obj.map._clear() assert len(global_obj.map.vertices()) == 0 - + # When - Deserialize objects new_param = Parameter.from_dict(param_dict) new_obj = ObjBase.from_dict(obj_dict) - + # Then - Should be registered in global map again assert len(global_obj.map.vertices()) >= 2 assert global_obj.map.is_known(new_param) assert global_obj.map.is_known(new_obj) - + # Objects should be functionally equivalent assert new_param.name == param.name assert new_param.value == param.value assert new_param.unit == param.unit - + def test_debug_mode_integration(self, clear_all): """Test debug mode behavior across the system""" # Given global_obj = GlobalObject() original_debug = global_obj.debug - + try: # When - Enable debug mode global_obj.debug = True - + if not global_obj.stack: global_obj.instantiate_stack() global_obj.stack.enabled = True - + # Create and modify objects - param = Parameter(name="debug_test", value=1.0) - + param = Parameter(name='debug_test', value=1.0) + # This should trigger debug output in property_stack decorator with patch('builtins.print') as mock_print: param.value = 2.0 - + # Should have printed debug info (if debug mode works) # Note: This depends on the debug implementation details - + # Test that operations still work normally assert param.value == 2.0 assert global_obj.stack.canUndo() - + finally: # Restore original debug state global_obj.debug = original_debug - + def test_concurrent_access_simulation(self, clear_all): """Simulate concurrent access patterns""" import threading import time - + # Given global_obj = GlobalObject() results = [] errors = [] - + def create_objects(thread_id, count=10): """Create objects in a thread""" try: for i in range(count): - param = Parameter(name=f"thread_{thread_id}_param_{i}", value=float(i)) + param = Parameter(name=f'thread_{thread_id}_param_{i}', value=float(i)) results.append(param.unique_name) time.sleep(0.001) # Small delay to encourage race conditions except Exception as e: - errors.append(f"Thread {thread_id}: {e}") - + errors.append(f'Thread {thread_id}: {e}') + # When - Create objects concurrently threads = [] for thread_id in range(3): thread = threading.Thread(target=create_objects, args=(thread_id, 5)) threads.append(thread) - + for thread in threads: thread.start() - + for thread in threads: thread.join() - + # Then - Should not have errors and all objects should be created - assert len(errors) == 0, f"Errors occurred: {errors}" + assert len(errors) == 0, f'Errors occurred: {errors}' assert len(results) == 15 # 3 threads * 5 objects each assert len(set(results)) == 15 # All unique names should be unique - + # All objects should be in the map for unique_name in results: - assert unique_name in global_obj.map.vertices() \ No newline at end of file + assert unique_name in global_obj.map.vertices() diff --git a/tests/unit_tests/global_object/test_map.py b/tests/unit/global_object/test_map.py similarity index 84% rename from tests/unit_tests/global_object/test_map.py rename to tests/unit/global_object/test_map.py index a2783e6e..c68aa96f 100644 --- a/tests/unit_tests/global_object/test_map.py +++ b/tests/unit/global_object/test_map.py @@ -1,133 +1,135 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause -from easyscience import Parameter -from easyscience import ObjBase -import pytest import gc -import weakref -import numpy as np -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock + +import pytest + +from easyscience import ObjBase +from easyscience import Parameter from easyscience import global_object -from easyscience.global_object.map import _EntryList, Map +from easyscience.global_object.map import Map +from easyscience.global_object.map import _EntryList + class TestEntryList: """Test the _EntryList helper class""" - + def test_init_default(self): """Test _EntryList initialization with defaults""" entry = _EntryList() assert entry._type == [] assert entry.finalizer is None - + def test_init_with_known_type(self): """Test _EntryList initialization with known type""" entry = _EntryList(my_type='created') assert 'created' in entry._type - + def test_init_with_unknown_type(self): """Test _EntryList initialization with unknown type""" entry = _EntryList(my_type='unknown') assert entry._type == [] - + def test_repr(self): """Test string representation""" entry = _EntryList() repr_str = str(entry) assert 'Undefined' in repr_str assert 'finalizer' in repr_str - + entry.type = 'created' repr_str = str(entry) assert 'created' in repr_str assert 'finalizer' in repr_str - + def test_type_property_getter(self): """Test type property getter""" entry = _EntryList() assert entry.type == [] - + def test_type_property_setter_valid(self): """Test type property setter with valid types""" entry = _EntryList() entry.type = 'created' assert 'created' in entry.type - + entry.type = 'argument' assert 'argument' in entry.type assert 'created' in entry.type # Should be additive - + def test_type_property_setter_invalid(self): """Test type property setter with invalid type""" entry = _EntryList() entry.type = 'invalid' assert entry.type == [] - + def test_type_property_setter_duplicate(self): """Test type property setter doesn't add duplicates""" entry = _EntryList() entry.type = 'created' entry.type = 'created' # Try to add again assert entry.type.count('created') == 1 - + def test_remove_type(self): """Test removing a type""" entry = _EntryList() entry.type = 'created' entry.type = 'argument' - + entry.remove_type('created') assert 'created' not in entry.type assert 'argument' in entry.type - + def test_remove_type_not_present(self): """Test removing a type that's not present""" entry = _EntryList() entry.type = 'created' entry.remove_type('argument') # Not present assert 'created' in entry.type - + def test_reset_type(self): """Test resetting types""" entry = _EntryList() entry.type = 'created' entry.type = 'argument' - + entry.reset_type('returned') assert entry.type == ['returned'] - + def test_reset_type_default_none(self): """Test resetting types with no default""" entry = _EntryList() entry.type = 'created' - + entry.reset_type() assert entry.type == [] - + def test_boolean_properties(self): """Test boolean property helpers""" entry = _EntryList() - + # Test all false initially assert not entry.is_argument assert not entry.is_created assert not entry.is_created_internal assert not entry.is_returned - + # Test each property entry.type = 'argument' assert entry.is_argument - + entry.type = 'created' assert entry.is_created - + entry.type = 'created_internal' assert entry.is_created_internal - + entry.type = 'returned' assert entry.is_returned + class TestMap: @pytest.fixture def clear(self): @@ -135,11 +137,11 @@ def clear(self): @pytest.fixture def base_object(self): - return ObjBase(name="test") + return ObjBase(name='test') @pytest.fixture def parameter_object(self): - return Parameter(name="test2", value=2) + return Parameter(name='test2', value=2) def test_add_vertex(self, clear, base_object, parameter_object): # When Then Expect @@ -158,7 +160,7 @@ def test_clear(self, clear, base_object): def test_weakref(self, clear): # When - test_obj = ObjBase(name="test") + test_obj = ObjBase(name='test') assert len(global_object.map._store) == 1 assert len(global_object.map._Map__type_dict) == 1 # Then @@ -170,81 +172,84 @@ def test_weakref(self, clear): def test_vertices(self, clear, base_object, parameter_object): # When Then Expect - assert global_object.map.vertices() == [base_object.unique_name, parameter_object.unique_name] + assert global_object.map.vertices() == [ + base_object.unique_name, + parameter_object.unique_name, + ] def test_get_item_by_key(self, clear, base_object, parameter_object): # When Then Expect assert global_object.map.get_item_by_key(base_object.unique_name) == base_object assert global_object.map.get_item_by_key(parameter_object.unique_name) == parameter_object - @pytest.mark.parametrize("cls, kwargs", [(ObjBase, {}), (Parameter, {"value": 2.0})]) + @pytest.mark.parametrize('cls, kwargs', [(ObjBase, {}), (Parameter, {'value': 2.0})]) def test_identical_unique_names_exception(self, clear, cls, kwargs): # When - test_obj = cls(name="test", unique_name="test", **kwargs) + test_obj = cls(name='test', unique_name='test', **kwargs) # Then Expect with pytest.raises(ValueError): - test_obj2 = cls(name="test2", unique_name="test", **kwargs) + test_obj2 = cls(name='test2', unique_name='test', **kwargs) def test_unique_name_change_still_in_map(self, clear, base_object, parameter_object): # When - assert global_object.map.get_item_by_key("ObjBase_0") == base_object - assert global_object.map.get_item_by_key("Parameter_0") == parameter_object + assert global_object.map.get_item_by_key('ObjBase_0') == base_object + assert global_object.map.get_item_by_key('Parameter_0') == parameter_object # Then - base_object.unique_name = "test3" - parameter_object.unique_name = "test4" + base_object.unique_name = 'test3' + parameter_object.unique_name = 'test4' # Expect - assert global_object.map.get_item_by_key("ObjBase_0") == base_object - assert global_object.map.get_item_by_key("Parameter_0") == parameter_object - assert global_object.map.get_item_by_key("test3") == base_object - assert global_object.map.get_item_by_key("test4") == parameter_object + assert global_object.map.get_item_by_key('ObjBase_0') == base_object + assert global_object.map.get_item_by_key('Parameter_0') == parameter_object + assert global_object.map.get_item_by_key('test3') == base_object + assert global_object.map.get_item_by_key('test4') == parameter_object def test_add_vertex_duplicate_name_error(self, clear, base_object): """Test that adding vertex with duplicate name raises error""" # When/Then - with pytest.raises(ValueError, match="already exists"): + with pytest.raises(ValueError, match='already exists'): # Try to add another object with same unique_name - duplicate_obj = ObjBase(name="duplicate", unique_name=base_object.unique_name) - + duplicate_obj = ObjBase(name='duplicate', unique_name=base_object.unique_name) + def test_add_vertex_with_object_type(self, clear): """Test adding vertex with specific object type""" # Given - obj = ObjBase(name="test") - + obj = ObjBase(name='test') + # When - Object is automatically added during construction # Then assert global_object.map.is_known(obj) assert 'created' in global_object.map.find_type(obj) - + def test_is_known_object(self, clear, base_object): """Test is_known method""" # When/Then assert global_object.map.is_known(base_object) is True - + # Test with unknown object unknown_obj = MagicMock() - unknown_obj.unique_name = "unknown" + unknown_obj.unique_name = 'unknown' assert global_object.map.is_known(unknown_obj) is False - + def test_find_type_known_object(self, clear, base_object): """Test find_type method""" # When/Then types = global_object.map.find_type(base_object) assert isinstance(types, list) assert 'created' in types - + def test_find_type_unknown_object(self, clear): """Test find_type with unknown object""" # Given unknown_obj = MagicMock() - unknown_obj.unique_name = "unknown" - + unknown_obj.unique_name = 'unknown' + # When/Then result = global_object.map.find_type(unknown_obj) assert result is None def test_returned_objs_access_safe_under_modification(self, clear): """Ensure accessing returned_objs doesn't raise when entries change size during iteration.""" - objs = [ObjBase(name=f"race_{i}") for i in range(8)] + objs = [ObjBase(name=f'race_{i}') for i in range(8)] # Mark all as returned for o in objs: global_object.map.change_type(o, 'returned') @@ -259,308 +264,312 @@ def test_returned_objs_access_safe_under_modification(self, clear): gc.collect() # If we got here without exceptions, consider the access safe assert True - + def test_reset_type(self, clear, base_object): """Test resetting object type""" # Given original_types = global_object.map.find_type(base_object) - + # When global_object.map.reset_type(base_object, 'argument') - + # Then new_types = global_object.map.find_type(base_object) assert new_types == ['argument'] assert new_types != original_types - + def test_change_type(self, clear, base_object): """Test changing object type""" # Given original_types = global_object.map.find_type(base_object) original_count = len(original_types) - + # When global_object.map.change_type(base_object, 'argument') - + # Then new_types = global_object.map.find_type(base_object) assert 'argument' in new_types assert len(new_types) >= original_count # Should be at least the same or more - + def test_add_edge(self, clear, base_object, parameter_object): """Test adding edges between objects""" # When global_object.map.add_edge(base_object, parameter_object) - + # Then edges = global_object.map.get_edges(base_object) assert parameter_object.unique_name in edges - + def test_add_edge_unknown_start_object(self, clear, parameter_object): """Test adding edge with unknown start object""" # Given unknown_obj = MagicMock() - unknown_obj.unique_name = "unknown" - + unknown_obj.unique_name = 'unknown' + # When/Then - with pytest.raises(AttributeError, match="Start object not in map"): + with pytest.raises(AttributeError, match='Start object not in map'): global_object.map.add_edge(unknown_obj, parameter_object) - + def test_get_edges(self, clear, base_object, parameter_object): """Test getting edges for an object""" # Given global_object.map.add_edge(base_object, parameter_object) - + # When edges = global_object.map.get_edges(base_object) - + # Then assert isinstance(edges, list) assert parameter_object.unique_name in edges - + def test_get_edges_unknown_object(self, clear): """Test getting edges for unknown object""" # Given unknown_obj = MagicMock() - unknown_obj.unique_name = "unknown" - + unknown_obj.unique_name = 'unknown' + # When/Then with pytest.raises(AttributeError): global_object.map.get_edges(unknown_obj) - + def test_prune_vertex_from_edge(self, clear, base_object, parameter_object): """Test removing edge between objects""" # Given global_object.map.add_edge(base_object, parameter_object) assert parameter_object.unique_name in global_object.map.get_edges(base_object) - + # When global_object.map.prune_vertex_from_edge(base_object, parameter_object) - + # Then edges = global_object.map.get_edges(base_object) assert parameter_object.unique_name not in edges - + def test_prune_vertex_from_edge_none_child(self, clear, base_object): """Test pruning edge with None child""" # When/Then - Should not raise error global_object.map.prune_vertex_from_edge(base_object, None) - + def test_prune_vertex(self, clear, base_object): """Test pruning a vertex completely""" # Given unique_name = base_object.unique_name assert global_object.map.is_known(base_object) - + # When global_object.map.prune(unique_name) - + # Then assert not global_object.map.is_known(base_object) assert unique_name not in global_object.map.vertices() - + def test_edges_generation(self, clear, base_object, parameter_object): """Test edge generation""" # Given global_object.map.add_edge(base_object, parameter_object) - + # When edges = global_object.map.edges() - + # Then assert isinstance(edges, list) expected_edge = {base_object.unique_name, parameter_object.unique_name} assert expected_edge in edges - + def test_type_filtering_properties(self, clear): """Test type filtering properties""" # Given - obj1 = ObjBase(name="obj1") # 'created' type - obj2 = Parameter(name="obj2", value=1) # 'created' type - + obj1 = ObjBase(name='obj1') # 'created' type + obj2 = Parameter(name='obj2', value=1) # 'created' type + global_object.map.change_type(obj1, 'argument') global_object.map.change_type(obj2, 'returned') - + # When/Then argument_objs = global_object.map.argument_objs created_objs = global_object.map.created_objs returned_objs = global_object.map.returned_objs - + assert obj1.unique_name in argument_objs assert obj1.unique_name in created_objs # Should still be there assert obj2.unique_name in created_objs assert obj2.unique_name in returned_objs - + def test_find_path_simple(self, clear, base_object, parameter_object): """Test finding path between objects""" # Given global_object.map.add_edge(base_object, parameter_object) - + # When path = global_object.map.find_path(base_object.unique_name, parameter_object.unique_name) - + # Then assert path == [base_object.unique_name, parameter_object.unique_name] - + def test_find_path_same_vertex(self, clear, base_object): """Test finding path to same vertex""" # When path = global_object.map.find_path(base_object.unique_name, base_object.unique_name) - + # Then assert path == [base_object.unique_name] - + def test_find_path_no_path(self, clear, base_object, parameter_object): """Test finding path when no path exists""" # When - No edge added path = global_object.map.find_path(base_object.unique_name, parameter_object.unique_name) - + # Then assert path == [] - + def test_find_all_paths(self, clear, base_object, parameter_object): """Test finding all paths between objects""" # Given global_object.map.add_edge(base_object, parameter_object) - + # When - paths = global_object.map.find_all_paths(base_object.unique_name, parameter_object.unique_name) - + paths = global_object.map.find_all_paths( + base_object.unique_name, parameter_object.unique_name + ) + # Then assert len(paths) == 1 assert paths[0] == [base_object.unique_name, parameter_object.unique_name] - + def test_reverse_route_with_start(self, clear, base_object, parameter_object): """Test reverse route with specified start""" # Given global_object.map.add_edge(base_object, parameter_object) - + # When - route = global_object.map.reverse_route(parameter_object.unique_name, base_object.unique_name) - + route = global_object.map.reverse_route( + parameter_object.unique_name, base_object.unique_name + ) + # Then assert route == [parameter_object.unique_name, base_object.unique_name] - + def test_reverse_route_without_start(self, clear, base_object, parameter_object): """Test reverse route without specified start""" # Given global_object.map.add_edge(base_object, parameter_object) - + # When route = global_object.map.reverse_route(parameter_object.unique_name) - + # Then assert len(route) >= 1 assert route[0] == parameter_object.unique_name - + def test_is_connected_single_vertex(self, clear, base_object): """Test connectivity with single vertex""" # When/Then assert global_object.map.is_connected() is True - + def test_is_connected_multiple_vertices(self, clear, base_object, parameter_object): """Test connectivity with multiple connected vertices""" # Given global_object.map.add_edge(base_object, parameter_object) - + # When/Then assert global_object.map.is_connected() is True - + def test_map_repr(self, clear, base_object, parameter_object): """Test map string representation""" # When repr_str = str(global_object.map) - + # Then - assert "Map object" in repr_str - assert "2" in repr_str # Should show vertex count - + assert 'Map object' in repr_str + assert '2' in repr_str # Should show vertex count + def test_get_item_by_key_not_found(self, clear): """Test getting item by non-existent key""" # When/Then - with pytest.raises(ValueError, match="Item not in map"): - global_object.map.get_item_by_key("non_existent") - + with pytest.raises(ValueError, match='Item not in map'): + global_object.map.get_item_by_key('non_existent') + def test_clear_with_finalizers(self, clear): """Test clearing map properly calls finalizers""" # Given - obj = ObjBase(name="test") + obj = ObjBase(name='test') original_count = len(global_object.map.vertices()) - + # When global_object.map._clear() - + # Then assert len(global_object.map.vertices()) == 0 - + def test_map_initialization(self): """Test Map initialization""" # When test_map = Map() - + # Then assert len(test_map.vertices()) == 0 assert test_map.edges() == [] def test_vertices_retry_on_runtime_error(self, clear): """Test that vertices() retries when RuntimeError occurs during iteration. - + This tests the thread-safety fix for WeakValueDictionary modification during iteration (e.g., by garbage collection). """ # Given test_map = Map() - + # Create a mock _store that raises RuntimeError on first iteration attempt call_count = 0 original_store = test_map._store - + class MockWeakValueDict: def __init__(self): self.data = {} self.iteration_count = 0 - + def __iter__(self): self.iteration_count += 1 if self.iteration_count == 1: # First iteration raises RuntimeError (simulates GC interference) - raise RuntimeError("dictionary changed size during iteration") + raise RuntimeError('dictionary changed size during iteration') # Subsequent iterations succeed return iter(self.data) - + def __len__(self): return len(self.data) - + mock_store = MockWeakValueDict() test_map._store = mock_store - + # When vertices = test_map.vertices() - + # Then assert vertices == [] assert mock_store.iteration_count == 2 # Should have retried once def test_add_vertex_cleans_stale_type_dict_entry(self, clear): """Test that add_vertex cleans up stale __type_dict entries. - + This can happen when a weak reference was collected but the finalizer hasn't run yet, and a new object is created with the same unique_name. """ # Given test_map = Map() - + # Manually add a stale entry to __type_dict (simulating GC collected but finalizer not run) - stale_name = "StaleObject_0" + stale_name = 'StaleObject_0' test_map._Map__type_dict[stale_name] = _EntryList() - + # Create a mock object with the same unique_name mock_obj = MagicMock() mock_obj.unique_name = stale_name - + # When - Adding the object should clean up the stale entry first test_map.add_vertex(mock_obj, 'created') - + # Then - Object should be added successfully assert stale_name in test_map._store assert stale_name in test_map._Map__type_dict @@ -568,20 +577,20 @@ def test_add_vertex_cleans_stale_type_dict_entry(self, clear): def test_prune_key_not_in_store(self, clear): """Test that prune handles case when key is not in _store. - + This defensive check prevents KeyError when the weak reference has already been garbage collected but __type_dict entry remains. """ # Given test_map = Map() - + # Manually add entry to __type_dict without corresponding _store entry - orphan_key = "OrphanObject_0" + orphan_key = 'OrphanObject_0' test_map._Map__type_dict[orphan_key] = _EntryList() - + # When - Pruning should not raise error test_map.prune(orphan_key) - + # Then - Entry should be removed from __type_dict assert orphan_key not in test_map._Map__type_dict @@ -591,10 +600,10 @@ def test_prune_key_in_both_dicts(self, clear, base_object): unique_name = base_object.unique_name assert unique_name in global_object.map._store assert unique_name in global_object.map._Map__type_dict - + # When global_object.map.prune(unique_name) - + # Then assert unique_name not in global_object.map._Map__type_dict # Note: _store entry may or may not exist depending on weak ref state @@ -602,14 +611,14 @@ def test_prune_key_in_both_dicts(self, clear, base_object): def test_prune_nonexistent_key(self, clear): """Test that prune handles nonexistent key gracefully.""" # When/Then - Should not raise error - global_object.map.prune("nonexistent_key") + global_object.map.prune('nonexistent_key') def test_reset_type_unknown_object(self, clear): """Test reset_type with object not in map.""" # Given unknown_obj = MagicMock() - unknown_obj.unique_name = "unknown" - + unknown_obj.unique_name = 'unknown' + # When/Then - Should not raise error global_object.map.reset_type(unknown_obj, 'argument') @@ -617,34 +626,34 @@ def test_change_type_unknown_object(self, clear): """Test change_type with object not in map.""" # Given unknown_obj = MagicMock() - unknown_obj.unique_name = "unknown" - + unknown_obj.unique_name = 'unknown' + # When/Then - Should not raise error global_object.map.change_type(unknown_obj, 'argument') def test_find_path_start_not_in_graph(self, clear): """Test find_path when start vertex is not in graph.""" # When - path = global_object.map.find_path("nonexistent", "also_nonexistent") - + path = global_object.map.find_path('nonexistent', 'also_nonexistent') + # Then assert path == [] def test_find_all_paths_start_not_in_graph(self, clear): """Test find_all_paths when start vertex is not in graph.""" # When - paths = global_object.map.find_all_paths("nonexistent", "also_nonexistent") - + paths = global_object.map.find_all_paths('nonexistent', 'also_nonexistent') + # Then assert paths == [] def test_find_isolated_vertices(self, clear, base_object, parameter_object): """Test finding isolated vertices (vertices with no outgoing edges).""" # Given - No edges added, both objects are isolated - + # When isolated = global_object.map.find_isolated_vertices() - + # Then assert base_object.unique_name in isolated assert parameter_object.unique_name in isolated @@ -653,10 +662,10 @@ def test_find_isolated_vertices_with_edges(self, clear, base_object, parameter_o """Test finding isolated vertices when some have edges.""" # Given global_object.map.add_edge(base_object, parameter_object) - + # When isolated = global_object.map.find_isolated_vertices() - + # Then # base_object has an edge, so it's not isolated assert base_object.unique_name not in isolated @@ -666,7 +675,7 @@ def test_find_isolated_vertices_with_edges(self, clear, base_object, parameter_o def test_prune_vertex_from_edge_edge_not_exists(self, clear, base_object, parameter_object): """Test pruning edge that doesn't exist.""" # Given - No edge added between objects - + # When/Then - Should not raise error global_object.map.prune_vertex_from_edge(base_object, parameter_object) @@ -674,20 +683,20 @@ def test_prune_vertex_from_edge_parent_not_in_map(self, clear, parameter_object) """Test pruning edge when parent is not in map.""" # Given unknown_obj = MagicMock() - unknown_obj.unique_name = "unknown" - + unknown_obj.unique_name = 'unknown' + # When/Then - Should not raise error (vertex1 not in type_dict) global_object.map.prune_vertex_from_edge(unknown_obj, parameter_object) def test_created_internal_property(self, clear): """Test created_internal property.""" # Given - obj = ObjBase(name="internal_obj") + obj = ObjBase(name='internal_obj') global_object.map.change_type(obj, 'created_internal') - + # When internal_objs = global_object.map.created_internal - + # Then assert obj.unique_name in internal_objs @@ -696,10 +705,10 @@ def test_clear_empties_both_dicts(self, clear, base_object, parameter_object): # Given assert len(global_object.map._store) == 2 assert len(global_object.map._Map__type_dict) == 2 - + # When global_object.map._clear() - + # Then assert len(global_object.map._store) == 0 assert len(global_object.map._Map__type_dict) == 0 @@ -708,18 +717,18 @@ def test_entry_list_delitem(self): """Test _EntryList __delitem__ method.""" # Given entry = _EntryList() - entry.append("item1") - entry.append("item2") - entry.append("item3") - + entry.append('item1') + entry.append('item2') + entry.append('item3') + # When del entry[1] - + # Then assert len(entry) == 2 - assert "item2" not in entry - assert "item1" in entry - assert "item3" in entry + assert 'item2' not in entry + assert 'item1' in entry + assert 'item3' in entry def test_entry_list_repr_with_finalizer(self): """Test _EntryList repr when finalizer is set.""" @@ -727,10 +736,10 @@ def test_entry_list_repr_with_finalizer(self): entry = _EntryList() entry.type = 'created' entry.finalizer = MagicMock() # Non-None finalizer - + # When repr_str = str(entry) - + # Then assert 'created' in repr_str assert 'With a finalizer' in repr_str @@ -740,10 +749,9 @@ def test_entry_list_remove_type_unknown(self): # Given entry = _EntryList() entry.type = 'created' - + # When - Try to remove unknown type entry.remove_type('unknown_type') - + # Then - Should not change anything assert 'created' in entry.type - diff --git a/tests/unit_tests/global_object/test_undo_redo.py b/tests/unit/global_object/test_undo_redo.py similarity index 77% rename from tests/unit_tests/global_object/test_undo_redo.py rename to tests/unit/global_object/test_undo_redo.py index 212681ac..be39eac3 100644 --- a/tests/unit_tests/global_object/test_undo_redo.py +++ b/tests/unit/global_object/test_undo_redo.py @@ -1,36 +1,35 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause import math import numpy as np import pytest -from easyscience.base_classes import CollectionBase -from easyscience.variable import DescriptorStr -from easyscience.variable import DescriptorBool -from easyscience import ObjBase -from easyscience import Parameter from easyscience import DescriptorNumber from easyscience import Fitter +from easyscience import ObjBase +from easyscience import Parameter +from easyscience.base_classes import CollectionBase +from easyscience.variable import DescriptorBool +from easyscience.variable import DescriptorStr def createSingleObjs(idx): - alphabet = "abcdefghijklmnopqrstuvwxyz" + alphabet = 'abcdefghijklmnopqrstuvwxyz' reps = math.floor(idx / len(alphabet)) + 1 name = alphabet[idx % len(alphabet)] * reps if idx % 2: - return Parameter(name, idx,unit="m/s") + return Parameter(name, idx, unit='m/s') else: - return DescriptorNumber(name, idx,unit="m/s") + return DescriptorNumber(name, idx, unit='m/s') def createParam(option): return pytest.param(option, id=option[0]) -def doUndoRedo(obj, attr, future, additional=""): +def doUndoRedo(obj, attr, future, additional=''): from easyscience import global_object global_object.stack.enabled = True @@ -44,7 +43,7 @@ def getter(_obj, _attr): try: previous = getter(obj, attr) - if attr == "unit" and hasattr(obj, "convert_unit"): + if attr == 'unit' and hasattr(obj, 'convert_unit'): obj.convert_unit(future) else: setattr(obj, attr, future) @@ -61,79 +60,82 @@ def getter(_obj, _attr): global_object.stack.enabled = False return e + @pytest.mark.parametrize( - "test", + 'test', [ createParam(option) for option in [ - ("value", 500), - ("error", 5), - ("unit", "km/s"), - ("display_name", "boom"), + ('value', 500), + ('error', 5), + ('unit', 'km/s'), + ('display_name', 'boom'), ] ], ) - def test_DescriptorNumberUndoRedo(test): - obj = DescriptorNumber('DescriptorNumber',1,unit='m/s') + obj = DescriptorNumber('DescriptorNumber', 1, unit='m/s') attr = test[0] value = test[1] e = doUndoRedo(obj, attr, value) assert not e + def test_DescriptorBoolUndoRedo(): - obj = DescriptorBool('DescriptorBool',False) + obj = DescriptorBool('DescriptorBool', False) attr = 'value' value = True e = doUndoRedo(obj, attr, value) assert not e - obj = DescriptorBool('DescriptorBool',True) + obj = DescriptorBool('DescriptorBool', True) attr = 'value' value = False e = doUndoRedo(obj, attr, value) assert not e + def test_DescriptorStrUndoRedo(): - obj = DescriptorStr('DescriptorStr','Foo') + obj = DescriptorStr('DescriptorStr', 'Foo') attr = 'value' value = 'Bar' e = doUndoRedo(obj, attr, value) assert not e + @pytest.mark.parametrize( - "test", + 'test', [ createParam(option) for option in [ - ("value", 500), - ("error", 5), - ("unit", "km/s"), - ("display_name", "boom"), - ("fixed", False), - ("max", 505), - ("min", -1), + ('value', 500), + ('error', 5), + ('unit', 'km/s'), + ('display_name', 'boom'), + ('fixed', False), + ('max', 505), + ('min', -1), ] ], ) - def test_ParameterUndoRedo(test): - obj = Parameter('Parameter',1,unit='m/s') + obj = Parameter('Parameter', 1, unit='m/s') attr = test[0] value = test[1] e = doUndoRedo(obj, attr, value) assert not e + def test_Parameter_Bounds_UndoRedo(): from easyscience import global_object global_object.stack.enabled = True - parameter = Parameter("test", 1) + parameter = Parameter('test', 1) assert parameter.min == -np.inf assert parameter.max == np.inf @@ -150,24 +152,24 @@ def test_Parameter_Bounds_UndoRedo(): def test_ObjBaseUndoRedo(): objs = {obj.name: obj for obj in [createSingleObjs(idx) for idx in range(5)]} - name = "test" + name = 'test' obj = ObjBase(name, **objs) - name2 = "best" + name2 = 'best' # Test name # assert not doUndoRedo(obj, 'name', name2) # Test setting value for b_obj in objs.values(): - e = doUndoRedo(obj, b_obj.name, b_obj.value + 1, "value") + e = doUndoRedo(obj, b_obj.name, b_obj.value + 1, 'value') assert not e def test_CollectionBaseUndoRedo(): objs = [createSingleObjs(idx) for idx in range(5)] - name = "test" + name = 'test' obj = CollectionBase(name, *objs) - name2 = "best" + name2 = 'best' # assert not doUndoRedo(obj, 'name', name2) @@ -176,7 +178,7 @@ def test_CollectionBaseUndoRedo(): global_object.stack.enabled = True original_length = len(obj) - p = Parameter("slip_in", 50) + p = Parameter('slip_in', 50) idx = 2 obj.insert(idx, p) assert len(obj) == original_length + 1 @@ -237,7 +239,7 @@ def test_CollectionBaseUndoRedo(): def test_UndoRedoMacros(): items = [createSingleObjs(idx) for idx in range(5)] offset = 5 - undo_text = "test_macro" + undo_text = 'test_macro' from easyscience import global_object global_object.stack.enabled = True @@ -263,7 +265,7 @@ def test_UndoRedoMacros(): assert item.value == old_value + offset -@pytest.mark.parametrize("fit_engine", ["LMFit", "Bumps", "DFO"]) +@pytest.mark.parametrize('fit_engine', ['LMFit', 'Bumps', 'DFO']) def test_fittingUndoRedo(fit_engine): m_value = 6 c_value = 2 @@ -273,18 +275,18 @@ def test_fittingUndoRedo(fit_engine): class Line(ObjBase): def __init__(self, m: Parameter, c: Parameter): - super(Line, self).__init__("basic_line", m=m, c=c) + super(Line, self).__init__('basic_line', m=m, c=c) @classmethod def default(cls): - m = Parameter("m", m_value) - c = Parameter("c", c_value) + m = Parameter('m', m_value) + c = Parameter('c', c_value) return cls(m=m, c=c) @classmethod def from_pars(cls, m_value: float, c_value: float): - m = Parameter("m", m_value) - c = Parameter("c", c_value) + m = Parameter('m', m_value) + c = Parameter('c', c_value) return cls(m=m, c=c) def __call__(self, x: np.ndarray) -> np.ndarray: @@ -304,7 +306,7 @@ def __call__(self, x: np.ndarray) -> np.ndarray: try: f.switch_minimizer(fit_engine) except AttributeError: - pytest.skip(msg=f"{fit_engine} is not installed") + pytest.skip(msg=f'{fit_engine} is not installed') from easyscience import global_object @@ -313,16 +315,17 @@ def __call__(self, x: np.ndarray) -> np.ndarray: # assert l1.c.value == pytest.approx(l2.c.value, rel=l2.c.error * 3) # assert l1.m.value == pytest.approx(l2.m.value, rel=l2.m.error * 3) - assert global_object.stack.undoText() == "Fitting routine" + assert global_object.stack.undoText() == 'Fitting routine' global_object.stack.undo() assert l2.m.value == m_sp assert l2.c.value == c_sp - assert global_object.stack.redoText() == "Fitting routine" + assert global_object.stack.redoText() == 'Fitting routine' global_object.stack.redo() - assert l2.m.value == res.p[f"p{l2.m.unique_name}"] - assert l2.c.value == res.p[f"p{l2.c.unique_name}"] + assert l2.m.value == res.p[f'p{l2.m.unique_name}'] + assert l2.c.value == res.p[f'p{l2.c.unique_name}'] + # TODO: Check if this test is needed # @pytest.mark.parametrize('math_funcs', [pytest.param([Parameter.__add__, float.__add__], id='Addition'), @@ -347,41 +350,41 @@ def __call__(self, x: np.ndarray) -> np.ndarray: # p2 = Parameter('b', b) # p1 = p_fun(p1, p2) - + # assert p1.value == result_value # global_object.stack.undo() # assert p1.value == a # global_object.stack.redo() # assert p1.value == result_value - # # Perform basic + error - # p1 = Parameter('a', a, error=sa) - # p2 = Parameter('b', b, error=sb) - # p1 = p_fun(p1, p2) - # assert p1.value == result_value - # assert p1.error == result_error - # global_object.stack.undo() - # assert p1.value == a - # assert p1.error == sa - # global_object.stack.redo() - # assert p1.value == result_value - # assert p1.error == result_error - - # # Perform basic + units - # p1 = Parameter('a', a, error=sa, units='m/s') - # p2 = Parameter('b', b, error=sb, units='m/s') - # p1 = p_fun(p1, p2) - # assert p1.value == result_value - # assert p1.error == result_error - # assert str(p1.unit) == 'meter / second' - # global_object.stack.undo() - # assert p1.value == a - # assert p1.error == sa - # assert str(p1.unit) == 'meter / second' - # global_object.stack.redo() - # assert p1.value == result_value - # assert p1.error == result_error - # assert str(p1.unit) == 'meter / second' +# # Perform basic + error +# p1 = Parameter('a', a, error=sa) +# p2 = Parameter('b', b, error=sb) +# p1 = p_fun(p1, p2) +# assert p1.value == result_value +# assert p1.error == result_error +# global_object.stack.undo() +# assert p1.value == a +# assert p1.error == sa +# global_object.stack.redo() +# assert p1.value == result_value +# assert p1.error == result_error + +# # Perform basic + units +# p1 = Parameter('a', a, error=sa, units='m/s') +# p2 = Parameter('b', b, error=sb, units='m/s') +# p1 = p_fun(p1, p2) +# assert p1.value == result_value +# assert p1.error == result_error +# assert str(p1.unit) == 'meter / second' +# global_object.stack.undo() +# assert p1.value == a +# assert p1.error == sa +# assert str(p1.unit) == 'meter / second' +# global_object.stack.redo() +# assert p1.value == result_value +# assert p1.error == result_error +# assert str(p1.unit) == 'meter / second' # @pytest.mark.parametrize('math_funcs', [pytest.param([Parameter.__imul__, float.__mul__, diff --git a/tests/unit_tests/global_object/test_undo_redo_comprehensive.py b/tests/unit/global_object/test_undo_redo_comprehensive.py similarity index 83% rename from tests/unit_tests/global_object/test_undo_redo_comprehensive.py rename to tests/unit/global_object/test_undo_redo_comprehensive.py index 024731a7..05264c1b 100644 --- a/tests/unit_tests/global_object/test_undo_redo_comprehensive.py +++ b/tests/unit/global_object/test_undo_redo_comprehensive.py @@ -1,142 +1,150 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause + +from unittest.mock import MagicMock +from unittest.mock import patch import pytest -import numpy as np -from unittest.mock import MagicMock, patch, call -from collections import deque -from easyscience import global_object, Parameter, ObjBase -from easyscience.global_object.undo_redo import ( - UndoCommand, UndoStack, PropertyStack, FunctionStack, - DictStack, DictStackReCreate, CommandHolder, NotarizedDict, - property_stack, dict_stack_deco -) +from easyscience.global_object.undo_redo import CommandHolder +from easyscience.global_object.undo_redo import DictStack +from easyscience.global_object.undo_redo import DictStackReCreate +from easyscience.global_object.undo_redo import FunctionStack +from easyscience.global_object.undo_redo import NotarizedDict +from easyscience.global_object.undo_redo import PropertyStack +from easyscience.global_object.undo_redo import UndoCommand +from easyscience.global_object.undo_redo import UndoStack +from easyscience.global_object.undo_redo import dict_stack_deco +from easyscience.global_object.undo_redo import property_stack + class MockUndoCommand(UndoCommand): """Mock implementation for testing""" + def __init__(self, obj, text=None): super().__init__(obj) if text: self.text = text self.undo_called = False self.redo_called = False - + def undo(self): self.undo_called = True - + def redo(self): self.redo_called = True + class TestUndoCommand: """Test abstract UndoCommand base class""" - + def test_init(self): """Test UndoCommand initialization""" obj = MagicMock() cmd = MockUndoCommand(obj) - + assert cmd._obj is obj assert cmd._text is None - + def test_text_property(self): """Test text property getter/setter""" cmd = MockUndoCommand(MagicMock()) - + # Test getter assert cmd.text is None - + # Test setter - cmd.text = "test text" - assert cmd.text == "test text" - + cmd.text = 'test text' + assert cmd.text == 'test text' + def test_abstract_methods(self): """Test that abstract methods are implemented""" cmd = MockUndoCommand(MagicMock()) - + # Should not raise NotImplementedError cmd.undo() cmd.redo() assert cmd.undo_called assert cmd.redo_called + class TestCommandHolder: """Test CommandHolder class""" - + def test_init_default(self): """Test CommandHolder initialization""" holder = CommandHolder() assert len(holder) == 0 - assert holder.text == "" + assert holder.text == '' assert not holder.is_macro - + def test_init_with_text(self): """Test CommandHolder initialization with text""" - holder = CommandHolder("test text") - assert holder._text == "test text" - + holder = CommandHolder('test text') + assert holder._text == 'test text' + def test_append_and_pop(self): """Test appending and popping commands""" holder = CommandHolder() cmd = MockUndoCommand(MagicMock()) - + holder.append(cmd) assert len(holder) == 1 assert holder.current is cmd - + popped = holder.pop() assert popped is cmd assert len(holder) == 0 - + def test_iteration(self): """Test iteration over commands""" holder = CommandHolder() - cmd1 = MockUndoCommand(MagicMock(), "cmd1") - cmd2 = MockUndoCommand(MagicMock(), "cmd2") - + cmd1 = MockUndoCommand(MagicMock(), 'cmd1') + cmd2 = MockUndoCommand(MagicMock(), 'cmd2') + holder.append(cmd1) holder.append(cmd2) - + commands = list(holder) assert len(commands) == 2 assert cmd2 in commands # Last appended should be first (LIFO) - + def test_is_macro_property(self): """Test is_macro property""" holder = CommandHolder() assert not holder.is_macro - + holder.append(MockUndoCommand(MagicMock())) assert not holder.is_macro - + holder.append(MockUndoCommand(MagicMock())) assert holder.is_macro - + def test_text_property_with_commands(self): """Test text property with commands""" holder = CommandHolder() - cmd = MockUndoCommand(MagicMock(), "command text") + cmd = MockUndoCommand(MagicMock(), 'command text') holder.append(cmd) - - assert holder.text == "command text" - + + assert holder.text == 'command text' + def test_text_property_override(self): """Test text property with override""" - holder = CommandHolder("override text") - cmd = MockUndoCommand(MagicMock(), "command text") + holder = CommandHolder('override text') + cmd = MockUndoCommand(MagicMock(), 'command text') holder.append(cmd) - - assert holder.text == "override text" + + assert holder.text == 'override text' + class TestUndoStack: """Test UndoStack class""" - + @pytest.fixture def stack(self): """Create a fresh UndoStack for each test""" return UndoStack() - + def test_init_default(self, stack): """Test UndoStack initialization""" assert stack.enabled is False @@ -144,389 +152,394 @@ def test_init_default(self, stack): assert len(stack.future) == 0 assert not stack._macro_running assert not stack._command_running - + def test_init_with_max_history(self): """Test UndoStack initialization with max history""" stack = UndoStack(max_history=5) assert stack._max_history == 5 assert stack.history.maxlen == 5 assert stack.future.maxlen == 5 - + def test_enabled_property(self, stack): """Test enabled property getter/setter""" assert not stack.enabled - + stack.enabled = True assert stack.enabled - + stack.enabled = False assert not stack.enabled - + def test_enabled_setter_with_running_macro(self, stack): """Test that setting enabled=False ends running macro""" stack.enabled = True - stack.beginMacro("test") + stack.beginMacro('test') assert stack._macro_running - + stack.enabled = False assert not stack._macro_running - + def test_force_state(self, stack): """Test force_state method""" stack.force_state(True) assert stack.enabled - + stack.force_state(False) assert not stack.enabled - + def test_push_disabled_stack(self, stack): """Test pushing command to disabled stack""" cmd = MockUndoCommand(MagicMock()) - + stack.push(cmd) - + assert cmd.redo_called assert len(stack.history) == 0 - + def test_push_enabled_stack(self, stack): """Test pushing command to enabled stack""" stack.enabled = True cmd = MockUndoCommand(MagicMock()) - + stack.push(cmd) - + assert cmd.redo_called assert len(stack.history) == 1 assert len(stack.future) == 0 - + def test_push_with_macro(self, stack): """Test pushing command during macro""" stack.enabled = True - stack.beginMacro("test macro") - + stack.beginMacro('test macro') + cmd1 = MockUndoCommand(MagicMock()) cmd2 = MockUndoCommand(MagicMock()) - + stack.push(cmd1) stack.push(cmd2) - + assert len(stack.history) == 1 # Only the macro holder assert len(stack.history[0]) == 2 # Two commands in the macro - + def test_push_clears_future(self, stack): """Test that push clears future stack""" stack.enabled = True cmd1 = MockUndoCommand(MagicMock()) cmd2 = MockUndoCommand(MagicMock()) - + stack.push(cmd1) stack.undo() assert len(stack.future) == 1 - + stack.push(cmd2) assert len(stack.future) == 0 - + def test_pop(self, stack): """Test popping last command""" stack.enabled = True cmd = MockUndoCommand(MagicMock()) - + stack.push(cmd) popped = stack.pop() - + assert popped is cmd assert len(stack.history) == 0 - + def test_pop_from_macro(self, stack): """Test popping from macro""" stack.enabled = True - stack.beginMacro("test") - + stack.beginMacro('test') + cmd1 = MockUndoCommand(MagicMock()) cmd2 = MockUndoCommand(MagicMock()) - + stack.push(cmd1) stack.push(cmd2) - + popped = stack.pop() assert popped is cmd2 assert len(stack.history[0]) == 1 # One command left in macro - + def test_clear(self, stack): """Test clearing the stack""" stack.enabled = True stack.push(MockUndoCommand(MagicMock())) - stack.beginMacro("test") - + stack.beginMacro('test') + stack.clear() - + assert len(stack.history) == 0 assert len(stack.future) == 0 assert not stack._macro_running - + def test_undo_success(self, stack): """Test successful undo operation""" stack.enabled = True cmd = MockUndoCommand(MagicMock()) - + stack.push(cmd) stack.undo() - + assert cmd.undo_called assert len(stack.history) == 0 assert len(stack.future) == 1 - + def test_undo_cannot_undo(self, stack): """Test undo when cannot undo""" assert not stack.canUndo() stack.undo() # Should not raise error - + def test_undo_with_exception(self, stack): """Test undo with exception in command""" stack.enabled = True - + class FailingCommand(UndoCommand): def undo(self): - raise Exception("test error") + raise Exception('test error') + def redo(self): pass - + cmd = FailingCommand(MagicMock()) stack.push(cmd) - + # Should not raise, just print error stack.undo() - + def test_redo_success(self, stack): """Test successful redo operation""" stack.enabled = True cmd = MockUndoCommand(MagicMock()) - + stack.push(cmd) stack.undo() stack.redo() - + assert cmd.redo_called assert len(stack.history) == 1 assert len(stack.future) == 0 - + def test_redo_cannot_redo(self, stack): """Test redo when cannot redo""" assert not stack.canRedo() stack.redo() # Should not raise error - + def test_macro_operations(self, stack): """Test macro begin/end operations""" stack.enabled = True - - stack.beginMacro("test macro") + + stack.beginMacro('test macro') assert stack._macro_running - + cmd1 = MockUndoCommand(MagicMock()) cmd2 = MockUndoCommand(MagicMock()) stack.push(cmd1) stack.push(cmd2) - + stack.endMacro() assert not stack._macro_running - + # Undo should undo both commands stack.undo() assert cmd1.undo_called assert cmd2.undo_called - + def test_macro_nested_error(self, stack): """Test error on nested macro""" stack.enabled = True - stack.beginMacro("test1") - - with pytest.raises(AssertionError, match="already running"): - stack.beginMacro("test2") - + stack.beginMacro('test1') + + with pytest.raises(AssertionError, match='already running'): + stack.beginMacro('test2') + def test_end_macro_without_begin_error(self, stack): """Test error on ending macro without begin""" stack.enabled = True - - with pytest.raises(AssertionError, match="not running"): + + with pytest.raises(AssertionError, match='not running'): stack.endMacro() - + def test_can_undo_redo_states(self, stack): """Test canUndo/canRedo state checking""" assert not stack.canUndo() assert not stack.canRedo() - + stack.enabled = True cmd = MockUndoCommand(MagicMock()) stack.push(cmd) - + assert stack.canUndo() assert not stack.canRedo() - + stack.undo() assert not stack.canUndo() assert stack.canRedo() - + def test_can_undo_redo_during_macro(self, stack): """Test canUndo/canRedo during macro""" stack.enabled = True stack.push(MockUndoCommand(MagicMock())) - - stack.beginMacro("test") + + stack.beginMacro('test') assert not stack.canUndo() # Cannot undo during macro assert not stack.canRedo() # Cannot redo during macro - + def test_undo_redo_text(self, stack): """Test undo/redo text retrieval""" stack.enabled = True - cmd = MockUndoCommand(MagicMock(), "test command") - + cmd = MockUndoCommand(MagicMock(), 'test command') + stack.push(cmd) - assert stack.undoText() == "test command" - assert stack.redoText() == "" - + assert stack.undoText() == 'test command' + assert stack.redoText() == '' + stack.undo() - assert stack.undoText() == "" - assert stack.redoText() == "test command" + assert stack.undoText() == '' + assert stack.redoText() == 'test command' + class TestPropertyStack: """Test PropertyStack command""" - + def test_init(self): """Test PropertyStack initialization""" parent = MagicMock() func = MagicMock() old_value = 10 new_value = 20 - + cmd = PropertyStack(parent, func, old_value, new_value) - + assert cmd._parent is parent assert cmd._set_func is func assert cmd._old_value == old_value assert cmd._new_value == new_value - assert "10" in cmd.text and "20" in cmd.text - + assert '10' in cmd.text and '20' in cmd.text + def test_init_with_custom_text(self): """Test PropertyStack with custom text""" - cmd = PropertyStack(MagicMock(), MagicMock(), 10, 20, "custom text") - assert cmd.text == "custom text" - + cmd = PropertyStack(MagicMock(), MagicMock(), 10, 20, 'custom text') + assert cmd.text == 'custom text' + def test_undo_redo(self): """Test PropertyStack undo/redo""" parent = MagicMock() func = MagicMock() - + cmd = PropertyStack(parent, func, 10, 20) - + cmd.undo() func.assert_called_once_with(parent, 10) - + func.reset_mock() cmd.redo() func.assert_called_once_with(parent, 20) + class TestFunctionStack: """Test FunctionStack command""" - + def test_init(self): """Test FunctionStack initialization""" parent = MagicMock() set_func = MagicMock() unset_func = MagicMock() - + cmd = FunctionStack(parent, set_func, unset_func) - + assert cmd._parent is parent assert cmd._old_fn is set_func assert cmd._new_fn is unset_func - + def test_undo_redo(self): """Test FunctionStack undo/redo""" set_func = MagicMock() unset_func = MagicMock() - + cmd = FunctionStack(MagicMock(), set_func, unset_func) - + cmd.undo() unset_func.assert_called_once() - + cmd.redo() set_func.assert_called_once() + class TestNotarizedDict: """Test NotarizedDict class""" - + def test_init(self): """Test NotarizedDict initialization""" nd = NotarizedDict(a=1, b=2) - + assert nd['a'] == 1 assert nd['b'] == 2 assert not nd._stack_enabled - + def test_setitem_without_stack(self): """Test setitem without stack enabled""" nd = NotarizedDict() nd['key'] = 'value' - + assert nd['key'] == 'value' - + def test_delitem_without_stack(self): """Test delitem without stack enabled""" nd = NotarizedDict(key='value') del nd['key'] - + assert 'key' not in nd - + def test_reorder_without_stack(self): """Test reorder without stack enabled""" nd = NotarizedDict(a=1, b=2) nd.reorder(b=2, a=1) - + assert list(nd.keys()) == ['b', 'a'] - + def test_repr(self): """Test string representation""" nd = NotarizedDict(a=1) repr_str = repr(nd) - + assert 'NotarizedDict' in repr_str assert "'a': 1" in repr_str + class TestDictStack: """Test DictStack command""" - + def test_init_deletion(self): """Test DictStack initialization for deletion""" nd = NotarizedDict(key='value') cmd = DictStack(nd, 'key') - + assert cmd._deletion is True assert cmd._creation is False assert cmd._key == 'key' assert cmd._old_value == 'value' assert cmd._index == 0 - + def test_init_creation(self): """Test DictStack initialization for creation""" nd = NotarizedDict() cmd = DictStack(nd, 'key', 'value') - + assert cmd._creation is True assert cmd._deletion is False assert cmd._key == 'key' assert cmd._new_value == 'value' - + def test_init_modification(self): """Test DictStack initialization for modification""" nd = NotarizedDict(key='old_value') cmd = DictStack(nd, 'key', 'new_value') - + assert not cmd._creation assert not cmd._deletion assert cmd._old_value == 'old_value' assert cmd._new_value == 'new_value' - + def test_undo_redo_creation(self): """Test undo/redo for creation""" nd = NotarizedDict() @@ -579,108 +592,114 @@ def test_undo_redo_deletion(self): cmd.redo() assert 'key' not in nd.data + class TestDictStackReCreate: """Test DictStackReCreate command""" - + def test_init(self): """Test DictStackReCreate initialization""" nd = NotarizedDict(a=1, b=2) new_dict = {'c': 3, 'd': 4} - + cmd = DictStackReCreate(nd, **new_dict) - + assert cmd._old_value == {'a': 1, 'b': 2} assert cmd._new_value == new_dict - + def test_undo_redo(self): """Test undo/redo operations""" nd = NotarizedDict(a=1, b=2) old_data = nd.data.copy() new_dict = {'c': 3, 'd': 4} - + cmd = DictStackReCreate(nd, **new_dict) - + cmd.undo() assert nd.data == old_data - + cmd.redo() assert nd.data == new_dict + class TestPropertyStackDecorator: """Test property_stack decorator""" - + def test_decorator_without_args(self): """Test decorator applied without arguments""" + @property_stack def test_func(obj, value): obj.value = value - + assert hasattr(test_func, 'func') - + def test_decorator_with_string_arg(self): """Test decorator applied with string argument""" - @property_stack("Custom text") + + @property_stack('Custom text') def test_func(obj, value): obj.value = value - + assert hasattr(test_func, 'func') - + def test_decorator_no_change_no_push(self): """Test decorator doesn't push when value unchanged""" + class TestObj: def __init__(self): self.value = 10 - + @property_stack def value(obj, new_value): obj.value = new_value - + obj = TestObj() - + with patch('easyscience.global_object') as mock_global: mock_stack = MagicMock() mock_global.stack = mock_stack - + value(obj, 10) # Same value - + # Should NOT have pushed anything since value didn't change mock_stack.push.assert_not_called() + class TestDictStackDecorator: """Test dict_stack_deco decorator""" - + def test_decorator_with_stack_disabled(self): """Test decorator when stack is disabled""" nd = NotarizedDict() nd._stack_enabled = False - + @dict_stack_deco def test_func(obj, key, value): obj[key] = value - + # Should call the function directly with patch('easyscience.global_object') as mock_global: mock_stack = MagicMock() mock_global.stack = mock_stack test_func(nd, 'key', 'value') mock_stack.push.assert_not_called() - + def test_decorator_with_stack_enabled(self): """Test decorator when stack is enabled""" nd = NotarizedDict() nd._stack_enabled = True - + @dict_stack_deco def test_func(obj, key, value): pass # Don't actually modify - + with patch('easyscience.global_object') as mock_global: mock_stack = MagicMock() mock_global.stack = mock_stack - + test_func(nd, 'key', 'value') - + # Should push a DictStack command mock_stack.push.assert_called_once() args = mock_stack.push.call_args[0] - assert isinstance(args[0], DictStack) \ No newline at end of file + assert isinstance(args[0], DictStack) diff --git a/tests/unit_tests/io/test_serializer_base.py b/tests/unit/io/test_serializer_base.py similarity index 73% rename from tests/unit_tests/io/test_serializer_base.py rename to tests/unit/io/test_serializer_base.py index 728dd1b6..c3c8dd21 100644 --- a/tests/unit_tests/io/test_serializer_base.py +++ b/tests/unit/io/test_serializer_base.py @@ -1,63 +1,67 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project +# SPDX-License-Identifier: BSD-3-Clause + import datetime -import json from enum import Enum -from unittest.mock import Mock, MagicMock, patch -from typing import Any, List, Optional +from typing import Any +from typing import List +from typing import Optional +from unittest.mock import MagicMock +from unittest.mock import Mock +from unittest.mock import patch import numpy as np import pytest -from easyscience import DescriptorNumber, Parameter, global_object +from easyscience import DescriptorNumber +from easyscience import Parameter +from easyscience import global_object +from easyscience.base_classes import NewBase from easyscience.io import SerializerBase from easyscience.io import SerializerComponent -from easyscience.base_classes import NewBase + class TestEnum(Enum): - TEST_VALUE = "test" + TEST_VALUE = 'test' ANOTHER_VALUE = 42 class MockSerializerComponent(SerializerComponent): """Mock serializer component for testing""" - - def __init__(self, name: str = "test", value: int = 1, - optional_param: Optional[str] = None, **kwargs): + + def __init__( + self, name: str = 'test', value: int = 1, optional_param: Optional[str] = None, **kwargs + ): self.name = name self.value = value self.optional_param = optional_param self._kwargs = kwargs - self.unique_name = f"mock_{name}" + self.unique_name = f'mock_{name}' self._global_object = True class MockSerializerWithRedirect(SerializerComponent): """Mock with _REDIRECT for testing redirect functionality""" - - _REDIRECT = { - 'special_attr': lambda obj: obj.value * 2, - 'none_attr': None - } - - def __init__(self, name: str = "test", value: int = 1, special_attr: int = 5): + + _REDIRECT = {'special_attr': lambda obj: obj.value * 2, 'none_attr': None} + + def __init__(self, name: str = 'test', value: int = 1, special_attr: int = 5): self.name = name self.value = value self.special_attr = special_attr - self.unique_name = f"redirect_{name}" + self.unique_name = f'redirect_{name}' self._global_object = True class MockSerializerWithConvertToDict(SerializerComponent): """Mock with custom _convert_to_dict method""" - - def __init__(self, name: str = "test", value: int = 1): + + def __init__(self, name: str = 'test', value: int = 1): self.name = name self.value = value - self.unique_name = f"custom_{name}" + self.unique_name = f'custom_{name}' self._global_object = True - + def _convert_to_dict(self, d, encoder, skip=None, **kwargs): d['custom_field'] = 'added_by_convert_to_dict' return d @@ -65,17 +69,16 @@ def _convert_to_dict(self, d, encoder, skip=None, **kwargs): class ConcreteSerializer(SerializerBase): """Concrete implementation for testing abstract methods""" - + def encode(self, obj: SerializerComponent, skip: Optional[List[str]] = None, **kwargs) -> Any: return self._convert_to_dict(obj, skip=skip, **kwargs) - + @classmethod def decode(cls, obj: Any) -> Any: return cls._convert_from_dict(obj) class TestSerializerBase: - @pytest.fixture def clear(self): """Clear everything before and after each test""" @@ -90,150 +93,138 @@ def clear(self): @pytest.fixture def serializer(self): return ConcreteSerializer() - + @pytest.fixture def mock_obj(self): - return MockSerializerComponent("test_obj", 42, "optional_value") - + return MockSerializerComponent('test_obj', 42, 'optional_value') + def test_abstract_methods_are_placeholders(self): """Test that SerializerBase can be instantiated but abstract methods just pass""" # SerializerBase can actually be instantiated (abstract methods just pass) base = SerializerBase() - + # Abstract methods don't raise exceptions - they just pass/return None result = base.encode(Mock()) assert result is None - + result = SerializerBase.decode({}) assert result is None - + def test_get_arg_spec(self): """Test get_arg_spec static method""" - def example_func(self, arg1, arg2, arg3="default"): + + def example_func(self, arg1, arg2, arg3='default'): pass - + spec, args = SerializerBase.get_arg_spec(example_func) - + assert args == ['arg1', 'arg2', 'arg3'] assert hasattr(spec, 'args') assert hasattr(spec, 'defaults') - + def test_encode_objs_datetime(self): """Test _encode_objs with datetime objects""" dt = datetime.datetime(2023, 10, 17, 14, 30, 45, 123456) result = SerializerBase._encode_objs(dt) - + expected = { '@module': 'datetime', - '@class': 'datetime', - 'string': '2023-10-17 14:30:45.123456' + '@class': 'datetime', + 'string': '2023-10-17 14:30:45.123456', } assert result == expected - + def test_encode_objs_numpy_array_real(self): """Test _encode_objs with real numpy arrays""" arr = np.array([1, 2, 3], dtype=np.int32) result = SerializerBase._encode_objs(arr) - - expected = { - '@module': 'numpy', - '@class': 'array', - 'dtype': 'int32', - 'data': [1, 2, 3] - } + + expected = {'@module': 'numpy', '@class': 'array', 'dtype': 'int32', 'data': [1, 2, 3]} assert result == expected - + def test_encode_objs_numpy_array_complex(self): """Test _encode_objs with complex numpy arrays""" - arr = np.array([1+2j, 3+4j], dtype=np.complex128) + arr = np.array([1 + 2j, 3 + 4j], dtype=np.complex128) result = SerializerBase._encode_objs(arr) - + expected = { '@module': 'numpy', '@class': 'array', 'dtype': 'complex128', - 'data': [[1.0, 3.0], [2.0, 4.0]] # [real, imag] + 'data': [[1.0, 3.0], [2.0, 4.0]], # [real, imag] } assert result == expected - + def test_encode_objs_numpy_scalar(self): """Test _encode_objs with numpy scalars""" scalar = np.int32(42) result = SerializerBase._encode_objs(scalar) - + assert result == 42 assert isinstance(result, int) - + def test_encode_objs_json_serializable(self): """Test _encode_objs with JSON serializable objects""" # Should return the object unchanged if it's JSON serializable - data = {"key": "value", "number": 42} + data = {'key': 'value', 'number': 42} result = SerializerBase._encode_objs(data) assert result == data - + def test_encode_objs_non_serializable(self): """Test _encode_objs with non-serializable objects""" + class NonSerializable: def __init__(self): - self.value = "test" - + self.value = 'test' + obj = NonSerializable() result = SerializerBase._encode_objs(obj) # Should return the object unchanged if not serializable assert result is obj - + def test_convert_from_dict_datetime(self): """Test _convert_from_dict with datetime objects""" dt_dict = { '@module': 'datetime', '@class': 'datetime', - 'string': '2023-10-17 14:30:45.123456' + 'string': '2023-10-17 14:30:45.123456', } - + result = SerializerBase._convert_from_dict(dt_dict) expected = datetime.datetime(2023, 10, 17, 14, 30, 45, 123456) assert result == expected - + def test_convert_from_dict_datetime_no_microseconds(self): """Test _convert_from_dict with datetime without microseconds""" - dt_dict = { - '@module': 'datetime', - '@class': 'datetime', - 'string': '2023-10-17 14:30:45' - } - + dt_dict = {'@module': 'datetime', '@class': 'datetime', 'string': '2023-10-17 14:30:45'} + result = SerializerBase._convert_from_dict(dt_dict) expected = datetime.datetime(2023, 10, 17, 14, 30, 45) assert result == expected - + def test_convert_from_dict_numpy_array_real(self): """Test _convert_from_dict with real numpy arrays""" - arr_dict = { - '@module': 'numpy', - '@class': 'array', - 'dtype': 'int32', - 'data': [1, 2, 3] - } - + arr_dict = {'@module': 'numpy', '@class': 'array', 'dtype': 'int32', 'data': [1, 2, 3]} + result = SerializerBase._convert_from_dict(arr_dict) expected = np.array([1, 2, 3], dtype=np.int32) np.testing.assert_array_equal(result, expected) assert result.dtype == expected.dtype - + def test_convert_from_dict_numpy_array_complex(self): """Test _convert_from_dict with complex numpy arrays""" arr_dict = { '@module': 'numpy', '@class': 'array', 'dtype': 'complex128', - 'data': [[1.0, 3.0], [2.0, 4.0]] + 'data': [[1.0, 3.0], [2.0, 4.0]], } - + result = SerializerBase._convert_from_dict(arr_dict) - expected = np.array([1+2j, 3+4j], dtype=np.complex128) + expected = np.array([1 + 2j, 3 + 4j], dtype=np.complex128) np.testing.assert_array_equal(result, expected) assert result.dtype == expected.dtype - + def test_convert_from_dict_easyscience_object(self, clear): """Test _convert_from_dict with EasyScience objects""" param_dict = { @@ -249,40 +240,40 @@ def test_convert_from_dict_easyscience_object(self, clear): 'fixed': False, 'url': '', 'description': '', - 'display_name': 'test_param' + 'display_name': 'test_param', } - + result = SerializerBase._convert_from_dict(param_dict) assert isinstance(result, Parameter) assert result.name == 'test_param' assert result.value == 5.0 assert str(result.unit) == 'm' - + def test_convert_from_dict_list(self): """Test _convert_from_dict with lists""" data = [ {'@module': 'datetime', '@class': 'datetime', 'string': '2023-10-17 14:30:45'}, {'key': 'value'}, - 42 + 42, ] - + result = SerializerBase._convert_from_dict(data) assert isinstance(result, list) assert len(result) == 3 assert isinstance(result[0], datetime.datetime) assert result[1] == {'key': 'value'} assert result[2] == 42 - + def test_convert_from_dict_regular_dict(self): """Test _convert_from_dict with regular dictionaries""" data = {'key': 'value', 'number': 42} result = SerializerBase._convert_from_dict(data) assert result == data - + def test_convert_to_dict_basic(self, serializer, mock_obj, clear): """Test _convert_to_dict with basic object""" result = serializer._convert_to_dict(mock_obj) - + assert '@module' in result assert '@class' in result assert '@version' in result @@ -294,42 +285,42 @@ def test_convert_to_dict_basic(self, serializer, mock_obj, clear): def test_convert_to_dict_with_skip(self, serializer, mock_obj, clear): """Test _convert_to_dict with skip parameter""" result = serializer._convert_to_dict(mock_obj, skip=['value', 'optional_param']) - + assert 'name' in result assert 'value' not in result assert 'optional_param' not in result def test_convert_to_dict_with_redirect(self, serializer, clear): """Test _convert_to_dict with _REDIRECT""" - obj = MockSerializerWithRedirect("redirect_test", 10) + obj = MockSerializerWithRedirect('redirect_test', 10) result = serializer._convert_to_dict(obj) - + assert result['special_attr'] == 20 # 10 * 2 from redirect assert 'none_attr' not in result # Should be skipped due to None redirect def test_convert_to_dict_with_custom_convert_to_dict(self, serializer, clear): """Test _convert_to_dict with custom _convert_to_dict method""" - obj = MockSerializerWithConvertToDict("custom_test", 5) + obj = MockSerializerWithConvertToDict('custom_test', 5) result = serializer._convert_to_dict(obj) - + assert result['custom_field'] == 'added_by_convert_to_dict' assert result['name'] == 'custom_test' assert result['value'] == 5 def test_convert_to_dict_with_enum_object(self, serializer, clear): """Test _convert_to_dict when the object itself is an enum""" - + # Test that enum values in objects remain as enums without full_encode class MockObjWithEnum(SerializerComponent): def __init__(self, name: str, enum_val: TestEnum): self.name = name self.enum_val = enum_val - self.unique_name = f"obj_{name}" + self.unique_name = f'obj_{name}' self._global_object = True - - obj = MockObjWithEnum("test", TestEnum.TEST_VALUE) + + obj = MockObjWithEnum('test', TestEnum.TEST_VALUE) result = serializer._convert_to_dict(obj) - + # The enum field should remain as an enum object (not encoded as dict) assert isinstance(result['enum_val'], TestEnum) assert result['enum_val'] == TestEnum.TEST_VALUE @@ -337,87 +328,87 @@ def __init__(self, name: str, enum_val: TestEnum): def test_convert_to_dict_full_encode(self, serializer, clear): """Test _convert_to_dict with full_encode=True""" dt = datetime.datetime(2023, 10, 17, 14, 30, 45) - + class MockObjWithDateTime(SerializerComponent): def __init__(self, name: str, dt: datetime.datetime): self.name = name self.dt = dt - self.unique_name = f"dt_{name}" + self.unique_name = f'dt_{name}' self._global_object = True - - obj = MockObjWithDateTime("test", dt) + + obj = MockObjWithDateTime('test', dt) result = serializer._convert_to_dict(obj, full_encode=True) - + assert isinstance(result['dt'], dict) assert result['dt']['@module'] == 'datetime' assert result['dt']['@class'] == 'datetime' def test_convert_to_dict_without_global_object(self, serializer): """Test _convert_to_dict with object without _global_object""" - + class MockObjNoGlobal(SerializerComponent): def __init__(self, name: str): self.name = name - - obj = MockObjNoGlobal("test") + + obj = MockObjNoGlobal('test') result = serializer._convert_to_dict(obj) - + assert result['name'] == 'test' assert 'unique_name' not in result def test_convert_to_dict_with_arg_spec(self, serializer, clear): """Test _convert_to_dict with custom _arg_spec""" - + class MockObjCustomArgSpec(SerializerComponent): - def __init__(self, name: str, value: int, extra: str = "default"): + def __init__(self, name: str, value: int, extra: str = 'default'): self.name = name self.value = value self.extra = extra self._arg_spec = ['name', 'value'] # Skip 'extra' - self.unique_name = f"custom_spec_{name}" + self.unique_name = f'custom_spec_{name}' self._global_object = True - - obj = MockObjCustomArgSpec("test", 42, "not_default") + + obj = MockObjCustomArgSpec('test', 42, 'not_default') result = serializer._convert_to_dict(obj) - + assert 'name' in result assert 'value' in result assert 'extra' not in result def test_recursive_encoder_with_lists(self, serializer, clear): """Test _recursive_encoder with lists""" - mock_obj = MockSerializerComponent("list_test", 1) - data = [mock_obj, "string", 42, {"key": "value"}] - + mock_obj = MockSerializerComponent('list_test', 1) + data = [mock_obj, 'string', 42, {'key': 'value'}] + result = serializer._recursive_encoder(data) - + assert isinstance(result, list) assert len(result) == 4 assert isinstance(result[0], dict) # Encoded mock object assert result[0]['name'] == 'list_test' - assert result[1] == "string" + assert result[1] == 'string' assert result[2] == 42 - assert result[3] == {"key": "value"} + assert result[3] == {'key': 'value'} def test_recursive_encoder_with_dicts(self, serializer, clear): """Test _recursive_encoder with dictionaries""" - mock_obj = MockSerializerComponent("dict_test", 2) - data = {"obj": mock_obj, "simple": "value"} - + mock_obj = MockSerializerComponent('dict_test', 2) + data = {'obj': mock_obj, 'simple': 'value'} + result = serializer._recursive_encoder(data) - + assert isinstance(result, dict) assert isinstance(result['obj'], dict) # Encoded mock object assert result['obj']['name'] == 'dict_test' - assert result['simple'] == "value" + assert result['simple'] == 'value' def test_recursive_encoder_with_tuples(self, serializer, clear): """Test _recursive_encoder with tuples""" - mock_obj = MockSerializerComponent("tuple_test", 3) - data = (mock_obj, "string", 42) - + mock_obj = MockSerializerComponent('tuple_test', 3) + data = (mock_obj, 'string', 42) + result = serializer._recursive_encoder(data) - + assert isinstance(result, list) # Tuples become lists assert len(result) == 3 assert isinstance(result[0], dict) # Encoded mock object @@ -426,22 +417,22 @@ def test_recursive_encoder_with_tuples(self, serializer, clear): def test_recursive_encoder_builtin_encode_method(self, serializer): """Test _recursive_encoder doesn't encode builtin objects with encode method""" # Strings have an encode method but are builtin - data = ["test_string", b"bytes"] - + data = ['test_string', b'bytes'] + result = serializer._recursive_encoder(data) - - assert result == ["test_string", b"bytes"] + + assert result == ['test_string', b'bytes'] def test_recursive_encoder_with_mutable_sequence(self, serializer, clear): """Test _recursive_encoder with MutableSequence objects""" from easyscience.base_classes import CollectionBase - - d0 = DescriptorNumber("a", 0) # type: ignore - d1 = DescriptorNumber("b", 1) # type: ignore - collection = CollectionBase("test_collection", d0, d1) - + + d0 = DescriptorNumber('a', 0) # type: ignore + d1 = DescriptorNumber('b', 1) # type: ignore + collection = CollectionBase('test_collection', d0, d1) + result = serializer._recursive_encoder(collection) - + assert isinstance(result, dict) assert result['@class'] == 'CollectionBase' assert 'data' in result @@ -452,77 +443,77 @@ def test_convert_to_dict_no_version(self, mock_import, serializer, clear): mock_module = Mock() del mock_module.__version__ # Remove version attribute mock_import.return_value = mock_module - - mock_obj = MockSerializerComponent("no_version", 1) + + mock_obj = MockSerializerComponent('no_version', 1) result = serializer._convert_to_dict(mock_obj) - + assert result['@version'] is None @patch('easyscience.io.serializer_base.import_module') def test_convert_to_dict_import_error(self, mock_import, serializer, clear): """Test _convert_to_dict when import_module raises ImportError""" - mock_import.side_effect = ImportError("Module not found") - - mock_obj = MockSerializerComponent("import_error", 1) + mock_import.side_effect = ImportError('Module not found') + + mock_obj = MockSerializerComponent('import_error', 1) result = serializer._convert_to_dict(mock_obj) - + assert result['@version'] is None def test_convert_to_dict_attribute_error_handling(self, serializer, clear): """Test _convert_to_dict handles AttributeError for missing attributes""" - + class MockObjMissingAttrs(SerializerComponent): - def __init__(self, name: str, missing_param: str = "default"): + def __init__(self, name: str, missing_param: str = 'default'): self.name = name - self.unique_name = f"missing_{name}" + self.unique_name = f'missing_{name}' self._global_object = True # Don't set missing_param attribute to trigger AttributeError - - obj = MockObjMissingAttrs("test") - - with pytest.raises(NotImplementedError, match="Unable to automatically determine as_dict"): + + obj = MockObjMissingAttrs('test') + + with pytest.raises(NotImplementedError, match='Unable to automatically determine as_dict'): serializer._convert_to_dict(obj) def test_convert_to_dict_with_kwargs_attribute(self, serializer, clear): """Test _convert_to_dict with _kwargs attribute handling""" - + class MockObjWithKwargs(SerializerComponent): def __init__(self, name: str, value: int): self.name = name self.value = value - self.unique_name = f"kwargs_{name}" + self.unique_name = f'kwargs_{name}' self._global_object = True # Set up _kwargs to test the kwargs handling path self._kwargs = {'extra_param': 'extra_value'} - - obj = MockObjWithKwargs("test", 42) + + obj = MockObjWithKwargs('test', 42) result = serializer._convert_to_dict(obj) - + # The extra_param from _kwargs should be included assert result['extra_param'] == 'extra_value' def test_convert_to_dict_varargs_handling(self, serializer, clear): """Test _convert_to_dict with varargs (*args) handling""" - + class MockObjWithVarargs(SerializerComponent): def __init__(self, name: str, *args): self.name = name self.args = args - self.unique_name = f"varargs_{name}" + self.unique_name = f'varargs_{name}' self._global_object = True - - obj = MockObjWithVarargs("test", "arg1", "arg2", "arg3") + + obj = MockObjWithVarargs('test', 'arg1', 'arg2', 'arg3') result = serializer._convert_to_dict(obj) - + assert result['name'] == 'test' if 'args' in result: - assert result['args'] == ("arg1", "arg2", "arg3") + assert result['args'] == ('arg1', 'arg2', 'arg3') def test_encode_objs_edge_cases(self): """Test _encode_objs with edge cases""" # Test with None assert SerializerBase._encode_objs(None) is None - + # Test with empty numpy array empty_arr = np.array([]) result = SerializerBase._encode_objs(empty_arr) @@ -533,33 +524,29 @@ def test_convert_from_dict_edge_cases(self): """Test _convert_from_dict with edge cases""" # Test with None assert SerializerBase._convert_from_dict(None) is None - + # Test with empty dict assert SerializerBase._convert_from_dict({}) == {} - + # Test with empty list assert SerializerBase._convert_from_dict([]) == [] - + # Test with bson.objectid (should not be processed) - bson_dict = { - '@module': 'bson.objectid', - '@class': 'ObjectId', - 'value': 'some_id' - } + bson_dict = {'@module': 'bson.objectid', '@class': 'ObjectId', 'value': 'some_id'} result = SerializerBase._convert_from_dict(bson_dict) assert result == bson_dict def test_concrete_serializer_implementation(self, clear): """Test that ConcreteSerializer works correctly""" serializer = ConcreteSerializer() - mock_obj = MockSerializerComponent("concrete_test", 100) - + mock_obj = MockSerializerComponent('concrete_test', 100) + # Test encode encoded = serializer.encode(mock_obj) assert isinstance(encoded, dict) assert encoded['name'] == 'concrete_test' assert encoded['value'] == 100 - + # Test decode global_object.map._clear() # Clear before decode decoded = ConcreteSerializer.decode(encoded) @@ -569,15 +556,16 @@ def test_concrete_serializer_implementation(self, clear): def test_get_arg_spec_with_complex_function(self): """Test get_arg_spec with more complex function signatures""" - def complex_func(self, required_arg, optional_arg="default", *args, **kwargs): + + def complex_func(self, required_arg, optional_arg='default', *args, **kwargs): pass - + spec, args = SerializerBase.get_arg_spec(complex_func) - + assert args == ['required_arg', 'optional_arg'] assert spec.varargs == 'args' assert spec.varkw == 'kwargs' - assert spec.defaults == ("default",) + assert spec.defaults == ('default',) @patch('easyscience.io.serializer_base.np', None) def test_encode_objs_without_numpy(self): @@ -585,64 +573,60 @@ def test_encode_objs_without_numpy(self): # This test patches np to None to simulate numpy not being installed dt = datetime.datetime(2023, 10, 17, 14, 30, 45) result = SerializerBase._encode_objs(dt) - - expected = { - '@module': 'datetime', - '@class': 'datetime', - 'string': '2023-10-17 14:30:45' - } + + expected = {'@module': 'datetime', '@class': 'datetime', 'string': '2023-10-17 14:30:45'} assert result == expected def test_recursive_encoder_with_nested_structures(self, serializer, clear): """Test _recursive_encoder with deeply nested structures""" - mock_obj = MockSerializerComponent("nested", 1) - - data = { - "level1": { - "level2": [mock_obj, {"level3": mock_obj}] - } - } - + mock_obj = MockSerializerComponent('nested', 1) + + data = {'level1': {'level2': [mock_obj, {'level3': mock_obj}]}} + result = serializer._recursive_encoder(data) - + assert isinstance(result, dict) - assert isinstance(result["level1"], dict) - assert isinstance(result["level1"]["level2"], list) - assert isinstance(result["level1"]["level2"][0], dict) # Encoded object - assert result["level1"]["level2"][0]["name"] == "nested" - assert isinstance(result["level1"]["level2"][1]["level3"], dict) # Encoded object + assert isinstance(result['level1'], dict) + assert isinstance(result['level1']['level2'], list) + assert isinstance(result['level1']['level2'][0], dict) # Encoded object + assert result['level1']['level2'][0]['name'] == 'nested' + assert isinstance(result['level1']['level2'][1]['level3'], dict) # Encoded object def test_import_class(self): # When Then - cls = SerializerBase._import_class(module_name="easyscience", class_name="Parameter") + cls = SerializerBase._import_class(module_name='easyscience', class_name='Parameter') # Expect assert cls is Parameter def test_import_class_missing_module(self): # When Then Expect with pytest.raises(ImportError): - SerializerBase._import_class(module_name="non_existent_module", class_name="Parameter") + SerializerBase._import_class(module_name='non_existent_module', class_name='Parameter') def test_import_class_missing_class(self): # When Then Expect with pytest.raises(ValueError): - SerializerBase._import_class(module_name="easyscience", class_name="NonExistentClass") - - @pytest.mark.parametrize("dict, expected", [ - ({ '@module': 'easyscience', - '@class': 'Parameter', - 'name': 'param1', - 'value': 10.0 - }, - True - ), - ({ - '@module': 'numpy', - '@class': 'array', - 'unique_name': 'unique1', - 'display_name': 'Display 1' - }, False - )], ids=['valid_easyscience_dict', 'invalid_numpy_dict']) + SerializerBase._import_class(module_name='easyscience', class_name='NonExistentClass') + + @pytest.mark.parametrize( + 'dict, expected', + [ + ( + {'@module': 'easyscience', '@class': 'Parameter', 'name': 'param1', 'value': 10.0}, + True, + ), + ( + { + '@module': 'numpy', + '@class': 'array', + 'unique_name': 'unique1', + 'display_name': 'Display 1', + }, + False, + ), + ], + ids=['valid_easyscience_dict', 'invalid_numpy_dict'], + ) def test_is_serialized_easyscience_object_false(self, dict, expected): # When Then result = SerializerBase._is_serialized_easyscience_object(dict) @@ -651,25 +635,20 @@ def test_is_serialized_easyscience_object_false(self, dict, expected): def test_deserialize_value_non_easyscience(self): # When - serialized_dict = { - '@module': 'numpy', - '@class': 'array', - 'dtype': 'int64', - 'data': [0, 1] - } + serialized_dict = {'@module': 'numpy', '@class': 'array', 'dtype': 'int64', 'data': [0, 1]} # Then obj = SerializerBase._deserialize_value(serialized_dict) # Expect - assert isinstance(obj, np.ndarray) + assert isinstance(obj, np.ndarray) assert obj.dtype == np.int64 def test_deserialize_value_easyscience_uses_from_dict(self, monkeypatch): # When serialized_dict = { - '@module': 'easyscience.base_classes', - '@class': 'NewBase', - 'display_name': 'test', - } + '@module': 'easyscience.base_classes', + '@class': 'NewBase', + 'display_name': 'test', + } monkeypatch.setattr(NewBase, 'from_dict', MagicMock()) # Then obj = SerializerBase._deserialize_value(serialized_dict) @@ -679,10 +658,10 @@ def test_deserialize_value_easyscience_uses_from_dict(self, monkeypatch): def test_deserialize_value_easyscience_no_from_dict(self, monkeypatch): # When serialized_dict = { - '@module': 'easyscience.base_classes', - '@class': 'NewBase', - 'display_name': 'test', - } + '@module': 'easyscience.base_classes', + '@class': 'NewBase', + 'display_name': 'test', + } monkeypatch.delattr(NewBase, 'from_dict') monkeypatch.setattr(SerializerBase, '_convert_from_dict', MagicMock()) # Then @@ -693,39 +672,40 @@ def test_deserialize_value_easyscience_no_from_dict(self, monkeypatch): def test_deserialize_value_easyscience_import_error(self, monkeypatch): # When serialized_dict = { - '@module': 'easyscience.base_classes', - '@class': 'NewBase', - 'display_name': 'test', - } + '@module': 'easyscience.base_classes', + '@class': 'NewBase', + 'display_name': 'test', + } monkeypatch.setattr(SerializerBase, '_import_class', MagicMock(side_effect=ImportError())) monkeypatch.setattr(SerializerBase, '_convert_from_dict', MagicMock()) # Then obj = SerializerBase._deserialize_value(serialized_dict) # Expect SerializerBase._convert_from_dict.assert_called_once_with(serialized_dict) - + def test_deserialize_dict(self, monkeypatch): # When serialized_dict = { - '@module': 'easyscience', + '@module': 'easyscience', '@class': 'ParameterContainer', 'param1': { '@module': 'easyscience', '@class': 'Parameter', 'name': 'param1', - 'value': 10.0 + 'value': 10.0, }, - 'array1': { - '@module': 'numpy', - '@class': 'array', - 'dtype': 'int64', - 'data': [0, 1] - } + 'array1': {'@module': 'numpy', '@class': 'array', 'dtype': 'int64', 'data': [0, 1]}, } - monkeypatch.setattr(SerializerBase, '_deserialize_value', MagicMock(side_effect=[ - Parameter(name='param1', value=10.0), - np.array([0, 1], dtype=np.int64) - ])) + monkeypatch.setattr( + SerializerBase, + '_deserialize_value', + MagicMock( + side_effect=[ + Parameter(name='param1', value=10.0), + np.array([0, 1], dtype=np.int64), + ] + ), + ) # Then result = SerializerBase.deserialize_dict(serialized_dict) # Expect @@ -733,4 +713,4 @@ def test_deserialize_dict(self, monkeypatch): SerializerBase._deserialize_value.assert_any_call(serialized_dict['array1']) assert isinstance(result['param1'], Parameter) assert isinstance(result['array1'], np.ndarray) - assert result['array1'].dtype == np.int64 \ No newline at end of file + assert result['array1'].dtype == np.int64 diff --git a/tests/unit/io/test_serializer_component.py b/tests/unit/io/test_serializer_component.py new file mode 100644 index 00000000..c4e21f49 --- /dev/null +++ b/tests/unit/io/test_serializer_component.py @@ -0,0 +1,96 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + +from copy import deepcopy +from typing import Type + +import numpy as np +import pytest + +import easyscience +from easyscience import DescriptorNumber +from easyscience import Parameter + +dp_param_dict = { + 'argnames': 'dp_kwargs, dp_cls', + 'argvalues': ( + [ + { + '@module': DescriptorNumber.__module__, + '@class': DescriptorNumber.__name__, + '@version': easyscience.__version__, + 'name': 'test', + 'value': 1.0, + 'variance': None, + 'unit': 'dimensionless', + 'description': '', + 'url': '', + 'display_name': 'test', + }, + DescriptorNumber, + ], + [ + { + '@module': Parameter.__module__, + '@class': Parameter.__name__, + '@version': easyscience.__version__, + 'name': 'test', + 'unit': 'km', + 'value': 1.0, + 'variance': 0.0, + 'min': -np.inf, + 'max': np.inf, + 'fixed': False, + 'url': 'https://www.boo.com', + 'description': '', + 'display_name': 'test', + }, + Parameter, + ], + ), + 'ids': ['DescriptorNumber', 'Parameter'], +} + +_skip_opt = [[], None] + [k for k in dp_param_dict['argvalues'][0][0].keys() if k[0] != '@'] +skip_dict = { + 'argnames': 'skip', + 'argvalues': _skip_opt, + 'ids': ['skip_' + str(opt) for opt in _skip_opt], +} + + +def check_dict(check, item): + if isinstance(check, dict) and isinstance(item, dict): + for key in check.keys(): + assert key in item.keys() + check_dict(check[key], item[key]) + else: + assert isinstance(item, type(check)) + assert item == check + + +@pytest.mark.parametrize(**skip_dict) +@pytest.mark.parametrize(**dp_param_dict) +def test_variable_as_dict_methods(dp_kwargs: dict, dp_cls: Type[DescriptorNumber], skip): + data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != '@'} + + obj = dp_cls(**data_dict) + + dp_kwargs = deepcopy(dp_kwargs) + + if isinstance(skip, str): + del dp_kwargs[skip] + + if not isinstance(skip, list): + skip = [skip] + + enc = obj.as_dict(skip=skip) + + expected_keys = set(dp_kwargs.keys()) + obtained_keys = set(enc.keys()) + + dif = expected_keys.difference(obtained_keys) + + assert len(dif) == 0 + + check_dict(dp_kwargs, enc) diff --git a/tests/unit_tests/io/test_serializer_dict.py b/tests/unit/io/test_serializer_dict.py similarity index 79% rename from tests/unit_tests/io/test_serializer_dict.py rename to tests/unit/io/test_serializer_dict.py index 7d75f02d..1ddf21ef 100644 --- a/tests/unit_tests/io/test_serializer_dict.py +++ b/tests/unit/io/test_serializer_dict.py @@ -1,17 +1,19 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause from copy import deepcopy from typing import Type import pytest -from easyscience.io.serializer_dict import SerializerDict from easyscience import DescriptorNumber from easyscience import ObjBase +from easyscience import global_object +from easyscience.io.serializer_dict import SerializerDict from .test_serializer_component import check_dict from .test_serializer_component import dp_param_dict from .test_serializer_component import skip_dict -from easyscience import global_object def recursive_remove(d, remove_keys: list) -> dict: @@ -36,7 +38,7 @@ def recursive_remove(d, remove_keys: list) -> dict: @pytest.mark.parametrize(**skip_dict) @pytest.mark.parametrize(**dp_param_dict) def test_variable_SerializerDict(dp_kwargs: dict, dp_cls: Type[DescriptorNumber], skip): - data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} + data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != '@'} obj = dp_cls(**data_dict) @@ -59,12 +61,13 @@ def test_variable_SerializerDict(dp_kwargs: dict, dp_cls: Type[DescriptorNumber] check_dict(dp_kwargs, enc) + ######################################################################################################################## # TESTING DECODING ######################################################################################################################## @pytest.mark.parametrize(**dp_param_dict) def test_variable_SerializerDict_decode(dp_kwargs: dict, dp_cls: Type[DescriptorNumber]): - data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} + data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != '@'} obj = dp_cls(**data_dict) @@ -76,12 +79,12 @@ def test_variable_SerializerDict_decode(dp_kwargs: dict, dp_cls: Type[Descriptor if hasattr(obj, k) and hasattr(dec, k): assert getattr(obj, k) == getattr(dec, k) else: - raise AttributeError(f"{k} not found in decoded object") + raise AttributeError(f'{k} not found in decoded object') @pytest.mark.parametrize(**dp_param_dict) def test_variable_SerializerDict_from_dict(dp_kwargs: dict, dp_cls: Type[DescriptorNumber]): - data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} + data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != '@'} obj = dp_cls(**data_dict) @@ -93,25 +96,26 @@ def test_variable_SerializerDict_from_dict(dp_kwargs: dict, dp_cls: Type[Descrip if hasattr(obj, k) and hasattr(dec, k): assert getattr(obj, k) == getattr(dec, k) else: - raise AttributeError(f"{k} not found in decoded object") + raise AttributeError(f'{k} not found in decoded object') + def test_group_encode(): - d0 = DescriptorNumber("a", 0) - d1 = DescriptorNumber("b", 1) + d0 = DescriptorNumber('a', 0) + d1 = DescriptorNumber('b', 1) from easyscience.base_classes import CollectionBase - b = CollectionBase("test", d0, d1) + b = CollectionBase('test', d0, d1) d = b.as_dict() - assert isinstance(d["data"], list) + assert isinstance(d['data'], list) def test_group_encode2(): - d0 = DescriptorNumber("a", 0) - d1 = DescriptorNumber("b", 1) + d0 = DescriptorNumber('a', 0) + d1 = DescriptorNumber('b', 1) from easyscience.base_classes import CollectionBase - b = ObjBase("outer", b=CollectionBase("test", d0, d1)) + b = ObjBase('outer', b=CollectionBase('test', d0, d1)) d = b.as_dict() - assert isinstance(d["b"], dict) \ No newline at end of file + assert isinstance(d['b'], dict) diff --git a/tests/unit/legacy/__init__.py b/tests/unit/legacy/__init__.py new file mode 100644 index 00000000..b1990ec8 --- /dev/null +++ b/tests/unit/legacy/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + diff --git a/tests/unit/legacy/test_dict.py b/tests/unit/legacy/test_dict.py new file mode 100644 index 00000000..b1990ec8 --- /dev/null +++ b/tests/unit/legacy/test_dict.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + diff --git a/tests/unit/legacy/test_json.py b/tests/unit/legacy/test_json.py new file mode 100644 index 00000000..b1990ec8 --- /dev/null +++ b/tests/unit/legacy/test_json.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + diff --git a/tests/unit/legacy/test_xml.py b/tests/unit/legacy/test_xml.py new file mode 100644 index 00000000..b1990ec8 --- /dev/null +++ b/tests/unit/legacy/test_xml.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + diff --git a/tests/unit/models/__init__.py b/tests/unit/models/__init__.py new file mode 100644 index 00000000..b1990ec8 --- /dev/null +++ b/tests/unit/models/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + diff --git a/tests/unit_tests/models/test_polynomial.py b/tests/unit/models/test_polynomial.py similarity index 92% rename from tests/unit_tests/models/test_polynomial.py rename to tests/unit/models/test_polynomial.py index 2493cd11..5376d03e 100644 --- a/tests/unit_tests/models/test_polynomial.py +++ b/tests/unit/models/test_polynomial.py @@ -1,7 +1,5 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2025 Contributors to the EasyScience project - +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause import numpy as np import pytest @@ -19,18 +17,18 @@ def clear(): poly_test_cases = ( - (1.,), + (1.0,), ( - 1., - 2., + 1.0, + 2.0, ), - (1., 2., 3.), - (-1., -2., -3.), + (1.0, 2.0, 3.0), + (-1.0, -2.0, -3.0), (0.72, 6.48, -0.48), ) -@pytest.mark.parametrize("coo", poly_test_cases) +@pytest.mark.parametrize('coo', poly_test_cases) def test_Polynomial_pars(clear, coo): poly = Polynomial(coefficients=coo) @@ -126,7 +124,7 @@ def test_Polynomial_invalid_coefficients_type(clear): """Test that invalid coefficients argument type raises TypeError.""" # String is iterable, so it will iterate over characters and fail with first error with pytest.raises(TypeError, match='Coefficients must be floats or Parameters'): - Polynomial(coefficients="invalid") + Polynomial(coefficients='invalid') # Integer is not iterable, so it will fail with second error with pytest.raises(TypeError, match='coefficients must be a list or a CollectionBase'): @@ -188,7 +186,7 @@ def test_Polynomial_call_with_args_kwargs(clear): x = np.array([0, 1, 2]) # These additional args/kwargs should be ignored - result = poly(x, "extra_arg", extra_kwarg="value") + result = poly(x, 'extra_arg', extra_kwarg='value') # polyval([1.0, 2.0, 3.0], x) = 1.0*x^2 + 2.0*x + 3.0 expected = np.polyval([1.0, 2.0, 3.0], x) assert np.allclose(result, expected) diff --git a/tests/unit/variable/__init__.py b/tests/unit/variable/__init__.py new file mode 100644 index 00000000..b1990ec8 --- /dev/null +++ b/tests/unit/variable/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + diff --git a/tests/unit_tests/variable/test_descriptor_any_type.py b/tests/unit/variable/test_descriptor_any_type.py similarity index 56% rename from tests/unit_tests/variable/test_descriptor_any_type.py rename to tests/unit/variable/test_descriptor_any_type.py index 70c4cc65..5dc28b58 100644 --- a/tests/unit_tests/variable/test_descriptor_any_type.py +++ b/tests/unit/variable/test_descriptor_any_type.py @@ -1,43 +1,48 @@ -import pytest +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import numpy as np +import pytest -from easyscience.variable import DescriptorAnyType from easyscience import global_object +from easyscience.variable import DescriptorAnyType + class TestDescriptorAnyType: @pytest.fixture def descriptor(self): descriptor = DescriptorAnyType( - name="name", - value="string", - description="description", - url="url", - display_name="display_name", + name='name', + value='string', + description='description', + url='url', + display_name='display_name', parent=None, ) return descriptor - + @pytest.fixture def clear(self): global_object.map._clear() def test_init(self, descriptor: DescriptorAnyType): # When Then Expect - assert descriptor._value == "string" + assert descriptor._value == 'string' # From super - assert descriptor._name == "name" - assert descriptor._description == "description" - assert descriptor._url == "url" - assert descriptor._display_name == "display_name" + assert descriptor._name == 'name' + assert descriptor._description == 'description' + assert descriptor._url == 'url' + assert descriptor._display_name == 'display_name' def test_value(self, descriptor: DescriptorAnyType): # When Then Expect - assert descriptor.value == "string" + assert descriptor.value == 'string' - - @pytest.mark.parametrize("value", [True, "new_string", 1.0, np.array([1, 2, 3]),{"key": "value"}]) - def test_set_value(self, descriptor: DescriptorAnyType,value): + @pytest.mark.parametrize( + 'value', [True, 'new_string', 1.0, np.array([1, 2, 3]), {'key': 'value'}] + ) + def test_set_value(self, descriptor: DescriptorAnyType, value): # When Then descriptor.value = value @@ -48,14 +53,14 @@ def test_set_value(self, descriptor: DescriptorAnyType,value): assert descriptor._value == value @pytest.mark.parametrize( - "value, expected", + 'value, expected', [ - (True, "True"), - ("new_string", "'new_string'"), - (1.0, "1.0"), - (np.array([1, 2, 3]), "array([1, 2, 3])"), - ({"key": "value"}, "{'key': 'value'}") - ] + (True, 'True'), + ('new_string', "'new_string'"), + (1.0, '1.0'), + (np.array([1, 2, 3]), 'array([1, 2, 3])'), + ({'key': 'value'}, "{'key': 'value'}"), + ], ) def test_repr(self, descriptor: DescriptorAnyType, value, expected): # Set the descriptor value @@ -75,4 +80,4 @@ def test_copy(self, descriptor: DescriptorAnyType): # Expect assert type(descriptor_copy) == DescriptorAnyType - assert descriptor_copy._value == descriptor._value \ No newline at end of file + assert descriptor_copy._value == descriptor._value diff --git a/tests/unit/variable/test_descriptor_array.py b/tests/unit/variable/test_descriptor_array.py new file mode 100644 index 00000000..73bb0857 --- /dev/null +++ b/tests/unit/variable/test_descriptor_array.py @@ -0,0 +1,1807 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + +import numpy as np +import pytest +import scipp as sc +from scipp import UnitError +from scipp.testing import assert_identical + +from easyscience import DescriptorNumber +from easyscience import global_object +from easyscience.variable import DescriptorArray + + +class TestDescriptorArray: + @pytest.fixture + def descriptor(self): + descriptor = DescriptorArray( + name='name', + value=[[1.0, 2.0], [3.0, 4.0]], + unit='m', + variance=[[0.1, 0.2], [0.3, 0.4]], + description='description', + url='url', + display_name='display_name', + parent=None, + ) + return descriptor + + @pytest.fixture + def descriptor_dimensionless(self): + descriptor = DescriptorArray( + name='name', + value=[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], + unit='dimensionless', + variance=[[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], + description='description', + url='url', + display_name='display_name', + parent=None, + ) + return descriptor + + @pytest.fixture + def clear(self): + global_object.map._clear() + + def test_init(self, descriptor: DescriptorArray): + # When Then Expect + assert np.array_equal(descriptor._array.values, np.array([[1.0, 2.0], [3.0, 4.0]])) + assert descriptor._array.unit == 'm' + assert np.array_equal(descriptor._array.variances, np.array([[0.1, 0.2], [0.3, 0.4]])) + + # From super + assert descriptor._name == 'name' + assert descriptor._description == 'description' + assert descriptor._url == 'url' + assert descriptor._display_name == 'display_name' + + def test_init_sc_unit(self): + # When Then + descriptor = DescriptorArray( + name='name', + value=[[1.0, 2.0], [3.0, 4.0]], + unit=sc.units.Unit('m'), + variance=[[0.1, 0.2], [0.3, 0.4]], + description='description', + url='url', + display_name='display_name', + parent=None, + ) + + # Expect + assert np.array_equal(descriptor._array.values, np.array([[1.0, 2.0], [3.0, 4.0]])) + assert descriptor._array.unit == 'm' + assert np.array_equal(descriptor._array.variances, np.array([[0.1, 0.2], [0.3, 0.4]])) + + def test_init_sc_unit_unknown(self): + # When Then Expect + with pytest.raises(UnitError): + DescriptorArray( + name='name', + value=[[1.0, 2.0], [3.0, 4.0]], + unit='unknown', + variance=[[0.1, 0.2], [0.3, 0.4]], + description='description', + url='url', + display_name='display_name', + parent=None, + ) + + @pytest.mark.parametrize('value', [True, 'string']) + def test_init_value_type_exception(self, value): + # When + + # Then Expect + with pytest.raises(TypeError): + DescriptorArray( + name='name', + value=value, + unit='m', + variance=[[0.1, 0.2], [0.3, 0.4]], + description='description', + url='url', + display_name='display_name', + parent=None, + ) + + def test_init_variance_exception(self): + # When + variance = [[-0.1, -0.2], [-0.3, -0.4]] + # Then Expect + with pytest.raises(ValueError): + DescriptorArray( + name='name', + value=[[1.0, 2.0], [3.0, 4.0]], + unit='m', + variance=variance, + description='description', + url='url', + display_name='display_name', + parent=None, + ) + + # test from_scipp + def test_from_scipp(self): + # When + full_value = sc.array(dims=['row', 'column'], values=[[1, 2], [3, 4]], unit='m') + # Then + descriptor = DescriptorArray.from_scipp(name='name', full_value=full_value) + + # Expect + assert np.array_equal(descriptor._array.values, [[1, 2], [3, 4]]) + assert descriptor._array.unit == 'm' + assert descriptor._array.variances == None + + # @pytest.mark.parametrize("full_value", [sc.array(values=[1,2], dimensions=["x"]), sc.array(values=[[1], [2]], dims=["x","y"]), object(), 1, "string"], ids=["1D", "2D", "object", "int", "string"]) + # def test_from_scipp_type_exception(self, full_value): + # # When Then Expect + # with pytest.raises(TypeError): + # DescriptorArray.from_scipp(name="name", full_value=full_value) + + def test_get_full_value(self, descriptor: DescriptorArray): + # When Then Expect + other = sc.array( + dims=('dim0', 'dim1'), + values=[[1.0, 2.0], [3.0, 4.0]], + unit='m', + variances=[[0.1, 0.2], [0.3, 0.4]], + ) + assert_identical(descriptor.full_value, other) + + def test_set_full_value(self, descriptor: DescriptorArray): + with pytest.raises(AttributeError): + descriptor.full_value = sc.array( + dims=['row', 'column'], values=[[1, 2], [3, 4]], unit='s' + ) + + def test_unit(self, descriptor: DescriptorArray): + # When Then Expect + assert descriptor.unit == 'm' + + def test_set_unit(self, descriptor: DescriptorArray): + with pytest.raises(AttributeError): + descriptor.unit = 's' + + def test_convert_unit(self, descriptor: DescriptorArray): + # When Then + descriptor.convert_unit('mm') + + # Expect + assert descriptor._array.unit == 'mm' + assert np.array_equal(descriptor._array.values, [[1000, 2000], [3000, 4000]]) + assert np.array_equal(descriptor._array.variances, [[100000, 200000], [300000, 400000]]) + + def test_variance(self, descriptor: DescriptorArray): + # When Then Expect + assert np.array_equal(descriptor._array.variances, np.array([[0.1, 0.2], [0.3, 0.4]])) + + def test_set_variance(self, descriptor: DescriptorArray): + # When Then + descriptor.variance = [[0.2, 0.3], [0.4, 0.5]] + + # Expect + assert np.array_equal(descriptor.variance, np.array([[0.2, 0.3], [0.4, 0.5]])) + assert np.array_equal(descriptor.error, np.sqrt(np.array([[0.2, 0.3], [0.4, 0.5]]))) + + def test_error(self, descriptor: DescriptorArray): + # When Then Expect + assert np.array_equal(descriptor.error, np.sqrt(np.array([[0.1, 0.2], [0.3, 0.4]]))) + + def test_set_error(self, descriptor: DescriptorArray): + # When Then + descriptor.error = np.sqrt(np.array([[0.2, 0.3], [0.4, 0.5]])) + # Expect + assert np.allclose(descriptor.error, np.sqrt(np.array([[0.2, 0.3], [0.4, 0.5]]))) + assert np.allclose(descriptor.variance, np.array([[0.2, 0.3], [0.4, 0.5]])) + + def test_value(self, descriptor: DescriptorArray): + # When Then Expect + assert np.array_equal(descriptor.value, np.array([[1, 2], [3, 4]])) + + def test_set_value(self, descriptor: DescriptorArray): + # When Then + descriptor.value = [[0.2, 0.3], [0.4, 0.5]] + # Expect + assert np.array_equal(descriptor._array.values, np.array([[0.2, 0.3], [0.4, 0.5]])) + + def test_repr(self, descriptor: DescriptorArray): + # When Then + repr_str = str(descriptor) + + # Expect + assert ( + repr_str + == "" + ) + + def test_copy(self, descriptor: DescriptorArray): + # When Then + descriptor_copy = descriptor.__copy__() + + # Expect + assert type(descriptor_copy) == DescriptorArray + assert np.array_equal(descriptor_copy._array.values, descriptor._array.values) + assert descriptor_copy._array.unit == descriptor._array.unit + + @pytest.mark.parametrize( + 'unit_string, expected', + [('1e+9', 'dimensionless'), ('1000', 'dimensionless'), ('10dm^2', 'm^2')], + ids=['scientific_notation', 'numbers', 'unit_prefix'], + ) + def test_base_unit(self, unit_string, expected): + # When + descriptor = DescriptorArray(name='name', value=[[1.0, 2.0], [3.0, 4.0]], unit=unit_string) + + # Then + base_unit = descriptor._base_unit() + + # Expect + assert base_unit == expected + + @pytest.mark.parametrize( + 'test, expected, raises_warning', + [ + ( + DescriptorNumber('test', 2, 'm', 0.01), + DescriptorArray( + 'test + name', [[3.0, 4.0], [5.0, 6.0]], 'm', [[0.11, 0.21], [0.31, 0.41]] + ), + True, + ), + ( + DescriptorNumber('test', 1, 'cm', 10), + DescriptorArray( + 'test + name', + [[1.01, 2.01], [3.01, 4.01]], + 'm', + [[0.1010, 0.2010], [0.3010, 0.4010]], + ), + True, + ), + ( + DescriptorArray('test', [[2.0, 3.0], [4.0, -5.0]], 'cm', [[1.0, 2.0], [3.0, 4.0]]), + DescriptorArray( + 'test + name', + [[1.02, 2.03], [3.04, 3.95]], + 'm', + [[0.1001, 0.2002], [0.3003, 0.4004]], + ), + False, + ), + ( + DescriptorArray('test', [[2, 3], [4, -5]], 'cm'), + DescriptorArray( + 'test + name', [[1.02, 2.03], [3.04, 3.95]], 'm', [[0.1, 0.2], [0.3, 0.4]] + ), + False, + ), + ], + ids=[ + 'descriptor_number_regular', + 'descriptor_number_unit_conversion', + 'array_conversion', + 'array_conversion_integer', + ], + ) + def test_addition(self, descriptor: DescriptorArray, test, expected, raises_warning): + # When Then + if raises_warning: + with pytest.warns(UserWarning) as record: + result = descriptor + test + assert len(record) == 1 + assert 'Correlations introduced' in record[0].message.args[0] + else: + result = descriptor + test + # Expect + assert type(result) == DescriptorArray + assert result.name == result.unique_name + assert np.array_equal(result.value, expected.value) + assert result.unit == expected.unit + assert np.allclose(result.variance, expected.variance) + assert descriptor.unit == 'm' + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + [[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], + DescriptorArray( + 'test', + [[3.0, 5.0], [7.0, -1.0], [11.0, -2.0]], + 'dimensionless', + [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], + ), + ), + ( + 1, + DescriptorArray( + 'test', + [[2.0, 3.0], [4.0, 5.0], [6.0, 7.0]], + 'dimensionless', + [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], + ), + ), + ], + ids=['list', 'number'], + ) + def test_addition_dimensionless( + self, descriptor_dimensionless: DescriptorArray, test, expected + ): + # When Then + result = descriptor_dimensionless + test + # Expect + assert type(result) == DescriptorArray + assert np.array_equal(result.value, expected.value) + assert np.allclose(result.variance, expected.variance) + assert descriptor_dimensionless.unit == 'dimensionless' + + @pytest.mark.parametrize( + 'test, expected, raises_warning', + [ + ( + DescriptorNumber('test', 2, 'm', 0.01), + DescriptorArray( + 'test + name', [[3.0, 4.0], [5.0, 6.0]], 'm', [[0.11, 0.21], [0.31, 0.41]] + ), + True, + ), + ( + DescriptorNumber('test', 1, 'cm', 10), + DescriptorArray( + 'test + name', + [[101.0, 201.0], [301.0, 401.0]], + 'cm', + [[1010.0, 2010.0], [3010.0, 4010.0]], + ), + True, + ), + ( + DescriptorArray('test', [[2.0, 3.0], [4.0, -5.0]], 'cm', [[1.0, 2.0], [3.0, 4.0]]), + DescriptorArray( + 'test + name', + [[102.0, 203.0], [304.0, 395.0]], + 'cm', + [[1001.0, 2002.0], [3003.0, 4004.0]], + ), + False, + ), + ( + DescriptorArray('test', [[2, 3], [4, -5]], 'cm'), + DescriptorArray( + 'test + name', + [[102.0, 203.0], [304.0, 395.0]], + 'cm', + [[1000.0, 2000.0], [3000.0, 4000.0]], + ), + False, + ), + ], + ids=[ + 'descriptor_number_regular', + 'descriptor_number_unit_conversion', + 'array_conversion', + 'array_conversion_integer', + ], + ) + def test_reverse_addition(self, descriptor: DescriptorArray, test, expected, raises_warning): + # When Then + if raises_warning: + with pytest.warns(UserWarning) as record: + result = test + descriptor + assert len(record) == 1 + assert 'Correlations introduced' in record[0].message.args[0] + else: + result = test + descriptor + # Expect + assert type(result) == DescriptorArray + assert result.name == result.unique_name + assert np.array_equal(result.value, expected.value) + assert result.unit == expected.unit + assert np.allclose(result.variance, expected.variance) + assert descriptor.unit == 'm' + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + [[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], + DescriptorArray( + 'test', + [[3.0, 5.0], [7.0, -1.0], [11.0, -2.0]], + 'dimensionless', + [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], + ), + ), + ( + 1, + DescriptorArray( + 'test', + [[2.0, 3.0], [4.0, 5.0], [6.0, 7.0]], + 'dimensionless', + [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], + ), + ), + ], + ids=['list', 'number'], + ) + def test_reverse_addition_dimensionless( + self, descriptor_dimensionless: DescriptorArray, test, expected + ): + # When Then + result = test + descriptor_dimensionless + # Expect + assert type(result) == DescriptorArray + assert np.array_equal(result.value, expected.value) + assert np.allclose(result.variance, expected.variance) + assert descriptor_dimensionless.unit == 'dimensionless' + + @pytest.mark.parametrize( + 'test, expected, raises_warning', + [ + ( + DescriptorNumber('test', 2, 'm', 0.01), + DescriptorArray( + 'test + name', [[-1.0, 0.0], [1.0, 2.0]], 'm', [[0.11, 0.21], [0.31, 0.41]] + ), + True, + ), + ( + DescriptorNumber('test', 1, 'cm', 10), + DescriptorArray( + 'test + name', + [[0.99, 1.99], [2.99, 3.99]], + 'm', + [[0.1010, 0.2010], [0.3010, 0.4010]], + ), + True, + ), + ( + DescriptorArray('test', [[2.0, 3.0], [4.0, -5.0]], 'cm', [[1.0, 2.0], [3.0, 4.0]]), + DescriptorArray( + 'test + name', + [[0.98, 1.97], [2.96, 4.05]], + 'm', + [[0.1001, 0.2002], [0.3003, 0.4004]], + ), + False, + ), + ( + DescriptorArray('test', [[2, 3], [4, -5]], 'cm'), + DescriptorArray( + 'test + name', + [[0.98, 1.97], [2.96, 4.05]], + 'm', + [[0.100, 0.200], [0.300, 0.400]], + ), + False, + ), + ], + ids=[ + 'descriptor_number_regular', + 'descriptor_number_unit_conversion', + 'array_conversion', + 'array_conversion_integer', + ], + ) + def test_subtraction(self, descriptor: DescriptorArray, test, expected, raises_warning): + # When Then + if raises_warning: + with pytest.warns(UserWarning) as record: + result = descriptor - test + assert len(record) == 1 + assert 'Correlations introduced' in record[0].message.args[0] + else: + result = descriptor - test + # Expect + assert type(result) == DescriptorArray + assert result.name == result.unique_name + assert np.array_equal(result.value, expected.value) + assert result.unit == expected.unit + assert np.allclose(result.variance, expected.variance) + assert descriptor.unit == 'm' + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + [[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], + DescriptorArray( + 'test', + [[-1.0, -1.0], [-1.0, 9.0], [-1, 14.0]], + 'dimensionless', + [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], + ), + ), + ( + 1, + DescriptorArray( + 'test', + [[0.0, 1.0], [2.0, 3.0], [4.0, 5.0]], + 'dimensionless', + [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], + ), + ), + ], + ids=['list', 'number'], + ) + def test_subtraction_dimensionless( + self, descriptor_dimensionless: DescriptorArray, test, expected + ): + # When Then + result = descriptor_dimensionless - test + # Expect + assert type(result) == DescriptorArray + assert np.array_equal(result.value, expected.value) + assert np.allclose(result.variance, expected.variance) + assert descriptor_dimensionless.unit == 'dimensionless' + + @pytest.mark.parametrize( + 'test, expected, raises_warning', + [ + ( + DescriptorNumber('test', 2, 'm', 0.01), + DescriptorArray( + 'test + name', [[1.0, 0.0], [-1.0, -2.0]], 'm', [[0.11, 0.21], [0.31, 0.41]] + ), + True, + ), + ( + DescriptorNumber('test', 1, 'cm', 10), + DescriptorArray( + 'test + name', + [[-99.0, -199.0], [-299.0, -399.0]], + 'cm', + [[1010.0, 2010.0], [3010.0, 4010.0]], + ), + True, + ), + ( + DescriptorArray('test', [[2.0, 3.0], [4.0, -5.0]], 'cm', [[1.0, 2.0], [3.0, 4.0]]), + DescriptorArray( + 'test + name', + [[-98.0, -197.0], [-296.0, -405.0]], + 'cm', + [[1001.0, 2002.0], [3003.0, 4004.0]], + ), + False, + ), + ( + DescriptorArray('test', [[2, 3], [4, -5]], 'cm'), + DescriptorArray( + 'test + name', + [[-98.0, -197.0], [-296.0, -405.0]], + 'cm', + [[1000.0, 2000.0], [3000.0, 4000.0]], + ), + False, + ), + ], + ids=[ + 'descriptor_number_regular', + 'descriptor_number_unit_conversion', + 'array_conversion', + 'array_conversion_integer', + ], + ) + def test_reverse_subtraction( + self, descriptor: DescriptorArray, test, expected, raises_warning + ): + # When Then + if raises_warning: + with pytest.warns(UserWarning) as record: + result = test - descriptor + assert len(record) == 1 + assert 'Correlations introduced' in record[0].message.args[0] + else: + result = test - descriptor + # Expect + assert type(result) == DescriptorArray + assert result.name == result.unique_name + assert np.array_equal(result.value, expected.value) + assert result.unit == expected.unit + assert np.allclose(result.variance, expected.variance) + assert descriptor.unit == 'm' + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + [[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], + DescriptorArray( + 'test', + [[1.0, 1.0], [1.0, -9.0], [1.0, -14.0]], + 'dimensionless', + [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], + ), + ), + ( + 1, + DescriptorArray( + 'test', + [[0.0, -1.0], [-2.0, -3.0], [-4.0, -5.0]], + 'dimensionless', + [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], + ), + ), + ], + ids=['list', 'number'], + ) + def test_reverse_subtraction_dimensionless( + self, descriptor_dimensionless: DescriptorArray, test, expected + ): + # When Then + result = test - descriptor_dimensionless + # Expect + assert type(result) == DescriptorArray + assert np.array_equal(result.value, expected.value) + assert np.allclose(result.variance, expected.variance) + assert descriptor_dimensionless.unit == 'dimensionless' + + @pytest.mark.parametrize( + 'test, expected, raises_warning', + [ + ( + DescriptorNumber('test', 2, 'm', 0.01), + DescriptorArray( + 'test * name', [[2.0, 4.0], [6.0, 8.0]], 'm^2', [[0.41, 0.84], [1.29, 1.76]] + ), + True, + ), + ( + DescriptorNumber('test', 1, 'cm', 10), + DescriptorArray( + 'test * name', + [[0.01, 0.02], [0.03, 0.04]], + 'm^2', + [[0.00101, 0.00402], [0.00903, 0.01604]], + ), + True, + ), + ( + DescriptorNumber('test', 1, 'kg', 10), + DescriptorArray( + 'test * name', [[1.0, 2.0], [3.0, 4.0]], 'kg*m', [[10.1, 40.2], [90.3, 160.4]] + ), + True, + ), + ( + DescriptorArray('test', [[2.0, 3.0], [4.0, -5.0]], 'cm', [[1.0, 2.0], [3.0, 4.0]]), + DescriptorArray( + 'test * name', + [[0.02, 0.06], [0.12, -0.2]], + 'm^2', + [[0.00014, 0.00098], [0.00318, 0.0074]], + ), + False, + ), + ( + DescriptorArray('test', [[2, 3], [4, -5]], 'cm'), + DescriptorArray( + 'test * name', + [[0.02, 0.06], [0.12, -0.2]], + 'm^2', + [ + [0.1 * 2**2 * 1e-4, 0.2 * 3**2 * 1e-4], + [0.3 * 4**2 * 1e-4, 0.4 * 5**2 * 1e-4], + ], + ), + False, + ), + ( + [[2.0, 3.0], [4.0, -5.0]], + DescriptorArray( + 'test * name', + [[2.0, 6.0], [12.0, -20.0]], + 'm', + [[0.1 * 2**2, 0.2 * 3**2], [0.3 * 4**2, 0.4 * 5**2]], + ), + False, + ), + ( + 2.0, + DescriptorArray( + 'test * name', + [[2.0, 4.0], [6.0, 8.0]], + 'm', + [[0.1 * 2**2, 0.2 * 2**2], [0.3 * 2**2, 0.4 * 2**2]], + ), + False, + ), + ], + ids=[ + 'descriptor_number_regular', + 'descriptor_number_unit_conversion', + 'descriptor_number_different_units', + 'array_conversion', + 'array_conversion_integer', + 'list', + 'number', + ], + ) + def test_multiplication(self, descriptor: DescriptorArray, test, expected, raises_warning): + # When Then + if raises_warning: + with pytest.warns(UserWarning) as record: + result = descriptor * test + assert len(record) == 1 + assert 'Correlations introduced' in record[0].message.args[0] + else: + result = descriptor * test + # Expect + assert type(result) == DescriptorArray + assert result.name == result.unique_name + assert np.array_equal(result.value, expected.value) + assert result.unit == expected.unit + assert np.allclose(result.variance, expected.variance) + assert descriptor.unit == 'm' + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + [[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], + DescriptorArray( + 'test', + [[2.0, 6.0], [12.0, -20.0], [30.0, -48.0]], + 'dimensionless', + [[0.4, 1.8], [4.8, 10.0], [18.0, 38.4]], + ), + ), + ( + 1.5, + DescriptorArray( + 'test', + [[1.5, 3.0], [4.5, 6.0], [7.5, 9.0]], + 'dimensionless', + [[0.225, 0.45], [0.675, 0.9], [1.125, 1.35]], + ), + ), + ], + ids=['list', 'number'], + ) + def test_multiplication_dimensionless( + self, descriptor_dimensionless: DescriptorArray, test, expected + ): + # When Then + result = descriptor_dimensionless * test + # Expect + assert type(result) == DescriptorArray + assert np.array_equal(result.value, expected.value) + assert np.allclose(result.variance, expected.variance) + assert descriptor_dimensionless.unit == 'dimensionless' + + @pytest.mark.parametrize( + 'test, expected, raises_warning', + [ + ( + DescriptorNumber('test', 2, 'm', 0.01), + DescriptorArray( + 'test * name', [[2.0, 4.0], [6.0, 8.0]], 'm^2', [[0.41, 0.84], [1.29, 1.76]] + ), + True, + ), + ( + DescriptorNumber('test', 1, 'cm', 10), + DescriptorArray( + 'test * name', + [[100.0, 200.0], [300.0, 400.0]], + 'cm^2', + [[101000.0, 402000.0], [903000.0, 1604000.0]], + ), + True, + ), + ( + DescriptorNumber('test', 1, 'kg', 10), + DescriptorArray( + 'test * name', [[1.0, 2.0], [3.0, 4.0]], 'kg*m', [[10.1, 40.2], [90.3, 160.4]] + ), + True, + ), + ( + DescriptorArray('test', [[2.0, 3.0], [4.0, -5.0]], 'cm', [[1.0, 2.0], [3.0, 4.0]]), + DescriptorArray( + 'test * name', + [[200.0, 600.0], [1200.0, -2000.0]], + 'cm^2', + [[14000.0, 98000.0], [318000.0, 740000.0]], + ), + False, + ), + ( + DescriptorArray('test', [[2, 3], [4, -5]], 'cm'), + DescriptorArray( + 'test * name', + [[200.0, 600.0], [1200.0, -2000.0]], + 'cm^2', + [[0.1 * 2**2 * 1e4, 0.2 * 3**2 * 1e4], [0.3 * 4**2 * 1e4, 0.4 * 5**2 * 1e4]], + ), + False, + ), + ( + [[2.0, 3.0], [4.0, -5.0]], + DescriptorArray( + 'test * name', + [[2.0, 6.0], [12.0, -20.0]], + 'm', + [[0.1 * 2**2, 0.2 * 3**2], [0.3 * 4**2, 0.4 * 5**2]], + ), + False, + ), + ( + 2.0, + DescriptorArray( + 'test * name', + [[2.0, 4.0], [6.0, 8.0]], + 'm', + [[0.1 * 2**2, 0.2 * 2**2], [0.3 * 2**2, 0.4 * 2**2]], + ), + False, + ), + ], + ids=[ + 'descriptor_number_regular', + 'descriptor_number_unit_conversion', + 'descriptor_number_different_units', + 'array_conversion', + 'array_conversion_integer', + 'list', + 'number', + ], + ) + def test_reverse_multiplication( + self, descriptor: DescriptorArray, test, expected, raises_warning + ): + # When Then + if raises_warning: + with pytest.warns(UserWarning) as record: + result = test * descriptor + assert len(record) == 1 + assert 'Correlations introduced' in record[0].message.args[0] + else: + result = test * descriptor + # Expect + assert type(result) == DescriptorArray + assert result.name == result.unique_name + assert np.array_equal(result.value, expected.value) + assert result.unit == expected.unit + assert np.allclose(result.variance, expected.variance) + assert descriptor.unit == 'm' + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + [[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], + DescriptorArray( + 'test', + [[2.0, 6.0], [12.0, -20.0], [30.0, -48.0]], + 'dimensionless', + [[0.4, 1.8], [4.8, 10.0], [18.0, 38.4]], + ), + ), + ( + 1.5, + DescriptorArray( + 'test', + [[1.5, 3.0], [4.5, 6.0], [7.5, 9.0]], + 'dimensionless', + [[0.225, 0.45], [0.675, 0.9], [1.125, 1.35]], + ), + ), + ], + ids=['list', 'number'], + ) + def test_reverse_multiplication_dimensionless( + self, descriptor_dimensionless: DescriptorArray, test, expected + ): + # When Then + result = test * descriptor_dimensionless + # Expect + assert type(result) == DescriptorArray + assert np.array_equal(result.value, expected.value) + assert np.allclose(result.variance, expected.variance) + assert descriptor_dimensionless.unit == 'dimensionless' + + @pytest.mark.parametrize( + 'test, expected, raises_warning', + [ + ( + DescriptorNumber('test', 2, 'm', 0.01), + DescriptorArray( + 'name / test', + [[1.0 / 2.0, 2.0 / 2.0], [3.0 / 2.0, 4.0 / 2.0]], + 'dimensionless', + [ + [ + (0.1 + 0.01 * 1.0**2 / 2.0**2) / 2.0**2, + (0.2 + 0.01 * 2.0**2 / 2.0**2) / 2.0**2, + ], + [ + (0.3 + 0.01 * 3.0**2 / 2.0**2) / 2.0**2, + (0.4 + 0.01 * 4.0**2 / 2.0**2) / 2.0**2, + ], + ], + ), + True, + ), + ( + DescriptorNumber('test', 1, 'cm', 10), + DescriptorArray( + 'name / test', + [[100.0, 200.0], [300.0, 400.0]], + 'dimensionless', + [ + [ + (0.1 + 10 * 1.0**2 / 1.0**2) / 1.0**2 * 1e4, + (0.2 + 10 * 2.0**2 / 1.0**2) / 1.0**2 * 1e4, + ], + [ + (0.3 + 10 * 3.0**2 / 1.0**2) / 1.0**2 * 1e4, + (0.4 + 10 * 4.0**2 / 1.0**2) / 1.0**2 * 1e4, + ], + ], + ), + True, + ), + ( + DescriptorNumber('test', 1, 'kg', 10), + DescriptorArray( + 'name / test', + [[1.0, 2.0], [3.0, 4.0]], + 'm/kg', + [ + [ + (0.1 + 10 * 1.0**2 / 1.0**2) / 1.0**2, + (0.2 + 10 * 2.0**2 / 1.0**2) / 1.0**2, + ], + [ + (0.3 + 10 * 3.0**2 / 1.0**2) / 1.0**2, + (0.4 + 10 * 4.0**2 / 1.0**2) / 1.0**2, + ], + ], + ), + True, + ), + ( + DescriptorArray( + 'test', [[2.0, 3.0], [4.0, -5.0]], 'cm^2', [[1.0, 2.0], [3.0, 4.0]] + ), + DescriptorArray( + 'name / test', + [[1 / 2 * 1e4, 2 / 3 * 1e4], [3.0 / 4.0 * 1e4, -4.0 / 5.0 * 1e4]], + '1/m', + [ + [ + (0.1 + 1.0 * 1.0**2 / 2.0**2) / 2.0**2 * 1e8, + (0.2 + 2.0 * 2.0**2 / 3.0**2) / 3.0**2 * 1e8, + ], + [ + (0.3 + 3.0 * 3.0**2 / 4.0**2) / 4.0**2 * 1e8, + (0.4 + 4.0 * 4.0**2 / 5.0**2) / 5.0**2 * 1e8, + ], + ], + ), + False, + ), + ( + DescriptorArray('test', [[2, 3], [4, -5]], 'cm^2'), + DescriptorArray( + 'name / test', + [[1 / 2 * 1e4, 2 / 3 * 1e4], [3.0 / 4.0 * 1e4, -4.0 / 5.0 * 1e4]], + '1/m', + [ + [(0.1) / 2.0**2 * 1e8, (0.2) / 3.0**2 * 1e8], + [(0.3) / 4.0**2 * 1e8, (0.4) / 5.0**2 * 1e8], + ], + ), + False, + ), + ( + [[2.0, 3.0], [4.0, -5.0]], + DescriptorArray( + 'name / name', + [[0.5, 2.0 / 3.0], [3.0 / 4.0, -4 / 5]], + 'm', + [[0.1 / 2**2, 0.2 / 3.0**2], [0.3 / 4**2, 0.4 / 5.0**2]], + ), + False, + ), + ( + 2.0, + DescriptorArray( + 'name / test', + [[0.5, 1.0], [3.0 / 2.0, 2.0]], + 'm', + [[0.1 / 2.0**2, 0.2 / 2.0**2], [0.3 / 2.0**2, 0.4 / 2.0**2]], + ), + False, + ), + ], + ids=[ + 'descriptor_number_regular', + 'descriptor_number_unit_conversion', + 'descriptor_number_different_units', + 'array_conversion', + 'array_conversion_integer', + 'list', + 'number', + ], + ) + def test_division(self, descriptor: DescriptorArray, test, expected, raises_warning): + # When Then + if raises_warning: + with pytest.warns(UserWarning) as record: + result = descriptor / test + assert len(record) == 1 + assert 'Correlations introduced' in record[0].message.args[0] + else: + result = descriptor / test + # Expect + assert type(result) == DescriptorArray + assert result.name == result.unique_name + assert np.allclose(result.value, expected.value) + assert result.unit == expected.unit + assert np.allclose(result.variance, expected.variance) + assert descriptor.unit == 'm' + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + [[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], + DescriptorArray( + 'test', + [[1.0 / 2.0, 2.0 / 3.0], [3.0 / 4.0, -4.0 / 5.0], [5.0 / 6.0, -6.0 / 8.0]], + 'dimensionless', + [ + [0.1 / 2.0**2, 0.2 / 3.0**2], + [0.3 / 4.0**2, 0.4 / 5.0**2], + [0.5 / 6.0**2, 0.6 / 8.0**2], + ], + ), + ), + ( + 2, + DescriptorArray( + 'test', + [[1.0 / 2.0, 2.0 / 2.0], [3.0 / 2.0, 4.0 / 2.0], [5.0 / 2.0, 6.0 / 2.0]], + 'dimensionless', + [ + [0.1 / 2.0**2, 0.2 / 2.0**2], + [0.3 / 2.0**2, 0.4 / 2.0**2], + [0.5 / 2.0**2, 0.6 / 2.0**2], + ], + ), + ), + ], + ids=['list', 'number'], + ) + def test_division_dimensionless( + self, descriptor_dimensionless: DescriptorArray, test, expected + ): + # When Then + result = descriptor_dimensionless / test + # Expect + assert type(result) == DescriptorArray + assert np.allclose(result.value, expected.value) + assert np.allclose(result.variance, expected.variance) + assert descriptor_dimensionless.unit == 'dimensionless' + + @pytest.mark.parametrize( + 'test, expected, raises_warning', + [ + ( + DescriptorNumber('test', 2, 'm', 0.01), + DescriptorArray( + 'test / name', + [[2.0, 1.0], [2.0 / 3.0, 0.5]], + 'dimensionless', + [ + [0.41, 0.0525], + [ + (0.01 + 0.3 * 2**2 / 3.0**2) / 3.0**2, + (0.01 + 0.4 * 2**2 / 4.0**2) / 4.0**2, + ], + ], + ), + True, + ), + ( + DescriptorNumber('test', 1, 'cm', 10), + DescriptorArray( + 'test / name', + [[1.0 / 100.0, 1.0 / 200.0], [1.0 / 300.0, 1.0 / 400.0]], + 'dimensionless', + [ + [1.01e-3, (1e-3 + 0.2 * 0.01**2 / 2**2) / 2**2], + [ + (1e-3 + 0.3 * 0.01**2 / 3**2) / 3**2, + (1e-3 + 0.4 * 0.01**2 / 4**2) / 4**2, + ], + ], + ), + True, + ), + ( + DescriptorNumber('test', 1, 'kg', 10), + DescriptorArray( + 'test / name', + [[1.0, 0.5], [1.0 / 3.0, 0.25]], + 'kg/m', + [ + [10.1, (10 + 0.2 * 1 / 2**2) / 2**2], + [(10 + 0.3 * 1 / 3**2) / 3**2, (10 + 0.4 * 1 / 4**2) / 4**2], + ], + ), + True, + ), + ( + DescriptorArray( + 'test', [[2.0, 3.0], [4.0, -5.0]], 'cm^2', [[1.0, 2.0], [3.0, 4.0]] + ), + DescriptorArray( + 'test / name', + [[2e-4, 1.5e-4], [4.0 / 3.0 * 1e-4, -1.25e-4]], + 'm', + [ + [1.4e-8, 6.125e-9], + [ + (3.0e-8 + 0.3 * (0.0004) ** 2 / 3**2) / 3**2, + (4.0e-8 + 0.4 * (0.0005) ** 2 / 4**2) / 4**2, + ], + ], + ), + False, + ), + ( + DescriptorArray('test', [[2, 3], [4, -5]], 'cm^2'), + DescriptorArray( + 'test / name', + [[2e-4, 1.5e-4], [4.0 / 3.0 * 1e-4, -1.25e-4]], + 'm', + [ + [ + (0.1 * 2.0**2 / 1.0**2) / 1.0**2 * 1e-8, + (0.2 * 3.0**2 / 2.0**2) / 2.0**2 * 1e-8, + ], + [ + (0.3 * 4.0**2 / 3.0**2) / 3.0**2 * 1e-8, + (0.4 * 5.0**2 / 4.0**2) / 4.0**2 * 1e-8, + ], + ], + ), + False, + ), + ( + [[2.0, 3.0], [4.0, -5.0]], + DescriptorArray( + 'test / name', + [[2, 1.5], [4.0 / 3.0, -1.25]], + '1/m', + [ + [0.1 * 2**2 / 1**4, 0.2 * 3.0**2 / 2.0**4], + [0.3 * 4**2 / 3**4, 0.4 * 5.0**2 / 4.0**4], + ], + ), + False, + ), + ( + 2.0, + DescriptorArray( + 'test / name', + [[2, 1.0], [2.0 / 3.0, 0.5]], + '1/m', + [ + [0.1 * 2**2 / 1**4, 0.2 * 2.0**2 / 2.0**4], + [0.3 * 2**2 / 3**4, 0.4 * 2.0**2 / 4.0**4], + ], + ), + False, + ), + ], + ids=[ + 'descriptor_number_regular', + 'descriptor_number_unit_conversion', + 'descriptor_number_different_units', + 'array_conversion', + 'array_conversion_integer', + 'list', + 'number', + ], + ) + def test_reverse_division(self, descriptor: DescriptorArray, test, expected, raises_warning): + # When Then + if raises_warning: + with pytest.warns(UserWarning) as record: + result = test / descriptor + assert len(record) == 1 + assert 'Correlations introduced' in record[0].message.args[0] + else: + result = test / descriptor + # Expect + assert type(result) == DescriptorArray + assert result.name == result.unique_name + assert np.allclose(result.value, expected.value) + assert result.unit == expected.unit + assert np.allclose(result.variance, expected.variance) + assert descriptor.unit == 'm' + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + [[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], + DescriptorArray( + 'test', + [[2.0 / 1.0, 3.0 / 2.0], [4.0 / 3.0, -5.0 / 4.0], [6.0 / 5.0, -8.0 / 6.0]], + 'dimensionless', + [ + [0.1 * 2.0**2, 0.2 * 3.0**2 / 2**4], + [0.3 * 4.0**2 / 3.0**4, 0.4 * 5.0**2 / 4**4], + [0.5 * 6.0**2 / 5**4, 0.6 * 8.0**2 / 6**4], + ], + ), + ), + ( + 2, + DescriptorArray( + 'test', + [[2.0, 1.0], [2.0 / 3.0, 0.5], [2.0 / 5.0, 1.0 / 3.0]], + 'dimensionless', + [ + [0.1 * 2.0**2, 0.2 / 2**2], + [0.3 * 2**2 / 3**4, 0.4 * 2**2 / 4**4], + [0.5 * 2**2 / 5**4, 0.6 * 2**2 / 6**4], + ], + ), + ), + ], + ids=['list', 'number'], + ) + def test_reverse_division_dimensionless( + self, descriptor_dimensionless: DescriptorArray, test, expected + ): + # When Then + result = test / descriptor_dimensionless + # Expect + assert type(result) == DescriptorArray + assert np.allclose(result.value, expected.value) + assert np.allclose(result.variance, expected.variance) + assert descriptor_dimensionless.unit == 'dimensionless' + + @pytest.mark.parametrize( + 'test', + [ + [[2.0, 3.0], [4.0, -5.0], [6.0, 0.0]], + 0.0, + DescriptorNumber('test', 0, 'cm', 10), + DescriptorArray( + 'test', + [[1.5, 0.0], [4.5, 6.0], [7.5, 9.0]], + 'dimensionless', + [[0.225, 0.45], [0.675, 0.9], [1.125, 1.35]], + ), + ], + ids=['list', 'number', 'DescriptorNumber', 'DescriptorArray'], + ) + def test_division_exception(self, descriptor_dimensionless: DescriptorArray, test): + # When Then + with pytest.raises(ZeroDivisionError): + descriptor_dimensionless / test + + # Also test reverse division where `self` is a DescriptorArray with a zero + zero_descriptor = DescriptorArray( + 'test', + [[1.5, 0.0], [4.5, 6.0], [7.5, 0.0]], + 'dimensionless', + [[0.225, 0.45], [0.675, 0.9], [1.125, 1.35]], + ) + with pytest.raises(ZeroDivisionError): + test / zero_descriptor + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + DescriptorNumber('test', 2, 'dimensionless'), + DescriptorArray( + 'test ** name', + [[1.0, 4.0], [9.0, 16.0]], + 'm^2', + [[4 * 0.1 * 1, 4 * 0.2 * 2**2], [4 * 0.3 * 3**2, 4 * 0.4 * 4**2]], + ), + ), + ( + DescriptorNumber('test', 3, 'dimensionless'), + DescriptorArray( + 'test ** name', + [[1.0, 8.0], [27, 64.0]], + 'm^3', + [[9 * 0.1, 9 * 0.2 * 2**4], [9 * 0.3 * 3**4, 9 * 0.4 * 4**4]], + ), + ), + ( + DescriptorNumber('test', 0.0, 'dimensionless'), + DescriptorArray( + 'test ** name', + [[1.0, 1.0], [1.0, 1.0]], + 'dimensionless', + [[0.0, 0.0], [0.0, 0.0]], + ), + ), + ( + 0.0, + DescriptorArray( + 'test ** name', + [[1.0, 1.0], [1.0, 1.0]], + 'dimensionless', + [[0.0, 0.0], [0.0, 0.0]], + ), + ), + ], + ids=[ + 'descriptor_number_squared', + 'descriptor_number_cubed', + 'descriptor_number_zero', + 'number_zero', + ], + ) + def test_power(self, descriptor: DescriptorArray, test, expected): + # When Then + result = descriptor**test + # Expect + assert type(result) == DescriptorArray + assert result.name == result.unique_name + assert np.array_equal(result.value, expected.value) + assert result.unit == expected.unit + assert np.allclose(result.variance, expected.variance) + assert descriptor.unit == 'm' + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + DescriptorNumber('test', 0.1, 'dimensionless'), + DescriptorArray( + 'test ** name', + [[1, 2**0.1], [3**0.1, 4**0.1], [5**0.1, 6**0.1]], + 'dimensionless', + [ + [0.1**2 * 0.1 * 1, 0.1**2 * 0.2 * 2 ** (-1.8)], + [0.1**2 * 0.3 * 3 ** (-1.8), 0.1**2 * 0.4 * 4 ** (-1.8)], + [0.1**2 * 0.5 * 5 ** (-1.8), 0.1**2 * 0.6 * 6 ** (-1.8)], + ], + ), + ), + ( + DescriptorNumber('test', 2.0, 'dimensionless'), + DescriptorArray( + 'test ** name', + [[1.0, 4.0], [9.0, 16.0], [25.0, 36.0]], + 'dimensionless', + [[0.4, 3.2], [10.8, 25.6], [50.0, 86.4]], + ), + ), + ], + ids=['descriptor_number_fractional', 'descriptor_number_integer'], + ) + def test_power_dimensionless(self, descriptor_dimensionless: DescriptorArray, test, expected): + # When Then + result = descriptor_dimensionless**test + # Expect + assert type(result) == DescriptorArray + assert result.name == result.unique_name + assert np.allclose(result.value, expected.value) + assert result.unit == expected.unit + assert np.allclose(result.variance, expected.variance) + assert descriptor_dimensionless.unit == 'dimensionless' + + @pytest.mark.parametrize( + 'test, exception', + [ + (DescriptorNumber('test', 2, 'm'), UnitError), + (DescriptorNumber('test', 2, 'dimensionless', 10), ValueError), + (DescriptorNumber('test', np.nan, 'dimensionless'), UnitError), + (DescriptorNumber('test', np.nan, 'dimensionless'), UnitError), + (DescriptorNumber('test', 1.5, 'dimensionless'), UnitError), + ( + DescriptorNumber('test', 0.5, 'dimensionless'), + UnitError, + ), # Square roots are not legal + ], + ids=[ + 'units', + 'variance', + 'scipp_nan', + 'nan_result', + 'non_integer_exponent_on_units', + 'square_root_on_units', + ], + ) + def test_power_exception(self, descriptor: DescriptorArray, test, exception): + # When Then + with pytest.raises(exception): + result = descriptor**2**test + with pytest.raises(ValueError): + # Exponentiation with an array does not make sense + test**descriptor + + @pytest.mark.parametrize( + 'test', + [DescriptorNumber('test', 2, 's'), DescriptorArray('test', [[1, 2], [3, 4]], 's')], + ids=['add_array_to_unit', 'incompatible_units'], + ) + def test_addition_exception(self, descriptor: DescriptorArray, test): + # When Then Expect + with pytest.raises(UnitError): + result = descriptor + test + with pytest.raises(UnitError): + result_reverse = test + descriptor + + @pytest.mark.parametrize( + 'test', + [DescriptorNumber('test', 2, 's'), DescriptorArray('test', [[1, 2], [3, 4]], 's')], + ids=['add_array_to_unit', 'incompatible_units'], + ) + def test_sub_exception(self, descriptor: DescriptorArray, test): + # When Then Expect + with pytest.raises(UnitError): + result = descriptor - test + with pytest.raises(UnitError): + result_reverse = test - descriptor + + @pytest.mark.parametrize( + 'function', + [np.sin, np.cos, np.exp, np.add, np.multiply], + ids=['sin', 'cos', 'exp', 'add', 'multiply'], + ) + def test_numpy_ufuncs_exception(self, descriptor_dimensionless, function): + ((np.add, np.array([[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]])),) + """ + Not implemented ufuncs should return NotImplemented. + """ + test = np.array([[1, 2], [3, 4]]) + with pytest.raises(TypeError) as e: + function(descriptor_dimensionless, test) + assert 'returned NotImplemented from' in str(e) + + def test_negation(self, descriptor): + # When + # Then + result = -descriptor + + # Expect + expected = DescriptorArray( + name='name', + value=[[-1.0, -2.0], [-3.0, -4.0]], + unit='m', + variance=[[0.1, 0.2], [0.3, 0.4]], + description='description', + url='url', + display_name='display_name', + parent=None, + ) + assert type(result) == DescriptorArray + assert result.name == result.unique_name + assert np.array_equal(result.value, expected.value) + assert result.unit == expected.unit + assert np.allclose(result.variance, expected.variance) + assert descriptor.unit == 'm' + + def test_abs(self, descriptor): + # When + negated = DescriptorArray( + name='name', + value=[[-1.0, -2.0], [-3.0, -4.0]], + unit='m', + variance=[[0.1, 0.2], [0.3, 0.4]], + description='description', + url='url', + display_name='display_name', + parent=None, + ) + + # Then + result = abs(negated) + + # Expect + assert type(result) == DescriptorArray + assert result.name == result.unique_name + assert np.array_equal(result.value, descriptor.value) + assert result.unit == descriptor.unit + assert np.allclose(result.variance, descriptor.variance) + assert descriptor.unit == 'm' + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + DescriptorArray( + 'test + name', [[3.0, 4.0], [5.0, 6.0]], 'm', [[0.11, 0.21], [0.31, 0.41]] + ), + DescriptorNumber('test', 9, 'm', 0.52), + ), + ( + DescriptorArray( + 'test + name', + [[101.0, 201.0], [301.0, 401.0]], + 'dimensionless', + [[1010.0, 2010.0], [3010.0, 4010.0]], + ), + DescriptorNumber('test', 502.0, 'dimensionless', 5020.0), + ), + ( + DescriptorArray('test', np.ones((9, 9)), 'dimensionless', np.ones((9, 9))), + DescriptorNumber('test', 9.0, 'dimensionless', 9.0), + ), + ( + DescriptorArray('test', np.ones((3, 3, 3)), 'dimensionless', np.ones((3, 3, 3))), + DescriptorArray( + 'test', + [3.0, 3.0, 3.0], + 'dimensionless', + [ + 3.0, + 3.0, + 3.0, + ], + dimensions=['dim2'], + ), + ), + ( + DescriptorArray('test', [[2.0]], 'dimensionless'), + DescriptorNumber('test', 2.0, 'dimensionless'), + ), + ], + ids=['2d_unit', '2d_dimensionless', '2d_large', '3d_dimensionless', '1d_dimensionless'], + ) + def test_trace(self, test: DescriptorArray, expected: DescriptorNumber): + result = test.trace() + assert type(result) == type(expected) + assert result.name == result.unique_name + assert np.array_equal(result.value, expected.value) + assert result.unit == expected.unit + if test.variance is not None: + assert np.allclose(result.variance, expected.variance) + if isinstance(expected, DescriptorArray): + assert np.all(result.full_value.dims == expected.full_value.dims) + + @pytest.mark.parametrize( + 'test, expected, dimensions', + [ + ( + DescriptorArray( + 'test', np.ones((3, 3, 4, 5)), 'dimensionless', np.ones((3, 3, 4, 5)) + ), + DescriptorArray( + 'test', + 3 * np.ones((3, 4)), + 'dimensionless', + 3 * np.ones((3, 4)), + dimensions=['dim0', 'dim2'], + ), + ('dim1', 'dim3'), + ) + ], + ids=['4d'], + ) + def test_trace_select_dimensions( + self, test: DescriptorArray, expected: DescriptorNumber, dimensions + ): + result = test.trace(dimension1=dimensions[0], dimension2=dimensions[1]) + assert type(result) == type(expected) + assert result.name == result.unique_name + assert np.array_equal(result.value.shape, expected.value.shape) + assert np.array_equal(result.value, expected.value) + assert result.unit == expected.unit + assert np.all(result.full_value.dims == expected.full_value.dims) + + @pytest.mark.parametrize( + 'test,dimensions,message', + [ + ( + DescriptorArray('test', np.ones((3, 3, 3)), 'dimensionless', np.ones((3, 3, 3))), + ('dim0', None), + 'Either both or none', + ), + ( + DescriptorArray('test', np.ones((3, 3, 3)), 'dimensionless', np.ones((3, 3, 3))), + ('dim0', 'dim0'), + 'must be different', + ), + ( + DescriptorArray('test', np.ones((3, 3, 3)), 'dimensionless', np.ones((3, 3, 3))), + ('dim0', 'dim1337'), + 'does not exist', + ), + ], + ids=['one_defined_dimension', 'same_dimension', 'invalid_dimension'], + ) + def test_trace_exception(self, test: DescriptorArray, dimensions, message): + with pytest.raises(ValueError) as e: + test.trace(dimension1=dimensions[0], dimension2=dimensions[1]) + assert message in str(e) + + def test_slicing(self, descriptor: DescriptorArray): + # When + first_value = descriptor['dim0', 0] + last_value = descriptor['dim0', -1] + second_array = descriptor['dim1', :] + + # Then + assert type(first_value) == DescriptorArray + assert type(last_value) == DescriptorArray + assert type(second_array) == DescriptorArray + + assert first_value.name != descriptor.unique_name + assert last_value.name != descriptor.unique_name + assert second_array.name != descriptor.unique_name + + assert np.array_equal( + first_value.full_value.values, descriptor.full_value['dim0', 0].values + ) + assert np.array_equal( + last_value.full_value.values, descriptor.full_value['dim0', -1].values + ) + assert np.array_equal( + second_array.full_value.values, descriptor.full_value['dim1', :].values + ) + + assert np.array_equal( + first_value.full_value.variances, descriptor.full_value['dim0', 0].variances + ) + assert np.array_equal( + last_value.full_value.variances, descriptor.full_value['dim0', -1].variances + ) + assert np.array_equal( + second_array.full_value.variances, descriptor.full_value['dim1', :].variances + ) + + assert np.array_equal(first_value.full_value.unit, descriptor.unit) + assert np.array_equal(last_value.full_value.unit, descriptor.unit) + assert np.array_equal(second_array.full_value.unit, descriptor.unit) + + def test_slice_deletion(self, descriptor: DescriptorArray): + with pytest.raises(AttributeError) as e: + del descriptor['dim0', 0] + assert 'has no attribute' in str(e) + + @pytest.mark.parametrize('test', [1.0, [3.0, 4.0, 5.0]], ids=['number', 'list']) + def test_slice_assignment_exception(self, descriptor_dimensionless: DescriptorArray, test): + # When + with pytest.raises(AttributeError) as e: + descriptor_dimensionless['dim0', :] = test + assert 'cannot be edited via slicing' in str(e) + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + DescriptorArray( + 'test + name', [[3.0, 4.0], [5.0, 6.0]], 'm', [[0.11, 0.21], [0.31, 0.41]] + ), + DescriptorNumber('test', 18, 'm', 1.04), + ), + ( + DescriptorArray( + 'test + name', + [[101.0, 201.0], [301.0, 401.0]], + 'cm', + [[1010.0, 2010.0], [3010.0, 4010.0]], + ), + DescriptorNumber('test', 1004.0, 'cm', 10040.0), + ), + ( + DescriptorArray('test', [[2.0, 3.0]], 'dimensionless', [[1.0, 2.0]]), + DescriptorNumber('test', 5.0, 'dimensionless', 3.0), + ), + ( + DescriptorArray('test', [[2.0, 3.0]], 'dimensionless'), + DescriptorNumber('test', 5.0, 'dimensionless'), + ), + ], + ids=[ + 'descriptor_array_m', + 'd=descriptor_array_cm', + 'descriptor_array_dimensionless', + 'descriptor_array_dim_varless', + ], + ) + def test_sum(self, test, expected): + result = test.sum() + assert type(result) == DescriptorNumber + assert result.name == result.unique_name + assert np.array_equal(result.value, expected.value) + assert result.unit == expected.unit + if test.variance is not None: + assert np.allclose(result.variance, expected.variance) + + @pytest.mark.parametrize( + 'expected, dim', + [ + (DescriptorArray('test', [4.0, 6.0], 'm', [0.4, 0.6]), 'dim0'), + (DescriptorArray('test', [3.0, 7.0], 'm', [0.3, 0.7]), 'dim1'), + ], + ids=['descriptor_array_dim0', 'descriptor_array_dim1'], + ) + def test_sum_over_subset(self, descriptor, expected, dim): + result = descriptor.sum(dim) + assert type(result) == type(expected) + assert result.name == result.unique_name + assert np.array_equal(result.value, expected.value) + assert result.unit == expected.unit + assert np.allclose(result.variance, expected.variance) + + @pytest.mark.parametrize( + 'test, dimensions', + [ + (DescriptorArray('test', [1.0], 'dimensionless', [1.0]), ['dim0']), + ( + DescriptorArray('test', [[1.0, 1.0]], 'dimensionless', [[1.0, 1.0]]), + ['dim0', 'dim1'], + ), + ( + DescriptorArray('test', [[1.0], [1.0]], 'dimensionless', [[1.0], [1.0]]), + ['dim0', 'dim1'], + ), + ( + DescriptorArray('test', [[[1.0, 1.0, 1.0]]], 'dimensionless', [[[1.0, 1.0, 1.0]]]), + ['dim0', 'dim1', 'dim2'], + ), + ( + DescriptorArray( + 'test', + [[[1.0]], [[1.0]], [[1.0]]], + 'dimensionless', + [[[1.0]], [[1.0]], [[1.0]]], + ), + ['dim0', 'dim1', 'dim2'], + ), + ], + ids=['1x1', '1x2', '2x1', '1x3', '3x1'], + ) + def test_array_generate_dimensions(self, test, dimensions): + assert test.dimensions == dimensions + + def test_array_set_dimensions_exception(self, descriptor): + with pytest.raises(ValueError) as e: + descriptor.dimensions = ['too_few'] + assert 'must have the same shape' + with pytest.raises(ValueError) as e: + DescriptorArray('test', [[1.0]], 'm', [[1.0]], dimensions=['dim']) + assert 'Length of dimensions' in str(e) + + def test_array_set_integer_value(self, descriptor): + """ + Scipp does not convert ints to floats, but values need to be floats for optimization. + """ + # When + descriptor.value = [[1, 2], [3, 4]] + # Then Expect + assert isinstance(descriptor.value[0][0], float) + + def test_array_set_integer_variance(self, descriptor): + # When + descriptor.variance = [[1, 2], [3, 4]] + # Then Expect + assert isinstance(descriptor.variance[0][0], float) + + def test_array_create_with_mixed_integers_and_floats(self): + # When + value = [[1, 2], [3, 4]] + variance = [[0.1, 0.2], [0.3, 0.4]] + # Then Expect + descriptor = DescriptorArray('test', value, 'dimensionless', variance) # Should not raise + assert isinstance(descriptor.value[0][0], float) + assert isinstance(descriptor.variance[0][0], float) + + def test_array_set_dims(self, descriptor): + # When + descriptor.dimensions = ['x', 'y'] + # Then Expect + assert descriptor.dimensions[0] == 'x' + assert descriptor.dimensions[1] == 'y' + assert descriptor.full_value.dims[0] == 'x' + assert descriptor.full_value.dims[1] == 'y' diff --git a/tests/unit/variable/test_descriptor_base.py b/tests/unit/variable/test_descriptor_base.py new file mode 100644 index 00000000..24c342dc --- /dev/null +++ b/tests/unit/variable/test_descriptor_base.py @@ -0,0 +1,225 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + +import pytest + +from easyscience import global_object +from easyscience.variable.descriptor_base import DescriptorBase + + +class TestDesciptorBase: + @pytest.fixture + def descriptor(self): + # This avoids the error: TypeError: Can't instantiate abstract class DescriptorBase with abstract methods __init__ + DescriptorBase.__abstractmethods__ = set() + DescriptorBase.__repr__ = lambda x: 'DescriptorBase' + self.objs_before_new_descriptor = len(global_object.map.created_objs) + descriptor = DescriptorBase( + name='name', + description='description', + url='url', + display_name='display_name', + parent=None, + ) + return descriptor + + @pytest.fixture + def clear(self): + global_object.map._clear() + + @pytest.mark.parametrize( + 'name', + [1, True, 1.0, [], {}, (), None, object()], + ids=['int', 'bool', 'float', 'list', 'dict', 'tuple', 'None', 'object'], + ) + def test_init_name_type_error(self, name): + # When Then + with pytest.raises(TypeError): + DescriptorBase( + name=name, + description='description', + url='url', + display_name='display_name', + parent=None, + ) + + @pytest.mark.parametrize( + 'display_name', + [1, True, 1.0, [], {}, (), object()], + ids=['int', 'bool', 'float', 'list', 'dict', 'tuple', 'object'], + ) + def test_init_display_name_type_error(self, display_name): + # When Then + with pytest.raises(TypeError): + DescriptorBase( + name='name', + description='description', + url='url', + display_name=display_name, + parent=None, + ) + + @pytest.mark.parametrize( + 'description', + [1, True, 1.0, [], {}, (), object()], + ids=['int', 'bool', 'float', 'list', 'dict', 'tuple', 'object'], + ) + def test_init_description_type_error(self, description): + # When Then + with pytest.raises(TypeError): + DescriptorBase( + name='name', + description=description, + url='url', + display_name='display_name', + parent=None, + ) + + @pytest.mark.parametrize( + 'url', + [1, True, 1.0, [], {}, (), object()], + ids=['int', 'bool', 'float', 'list', 'dict', 'tuple', 'object'], + ) + def test_init_url_type_error(self, url): + # When Then + with pytest.raises(TypeError): + DescriptorBase( + name='name', + description='description', + url=url, + display_name='display_name', + parent=None, + ) + + def test_init(self, descriptor: DescriptorBase): + assert descriptor._name == 'name' + assert descriptor._description == 'description' + assert descriptor._url == 'url' + assert descriptor._display_name == 'display_name' + assert len(global_object.map.created_objs) - self.objs_before_new_descriptor == 1 + + def test_display_name(self, descriptor: DescriptorBase): + # When Then Expect + assert descriptor.display_name == 'display_name' + + def test_display_name_none(self, descriptor: DescriptorBase): + # When + descriptor._display_name = None + # Then Expect + assert descriptor.display_name == 'name' + + def test_display_name_setter(self, descriptor: DescriptorBase): + # When + descriptor.display_name = 'new_display_name' + # Then Expect + assert descriptor.display_name == 'new_display_name' + + @pytest.mark.parametrize( + 'display_name', + [1, True, 1.0, [], {}, (), object()], + ids=['int', 'bool', 'float', 'list', 'dict', 'tuple', 'object'], + ) + def test_display_name_setter_type_error(self, descriptor: DescriptorBase, display_name): + # When Then + with pytest.raises(TypeError): + descriptor.display_name = display_name + + def test_name_setter(self, descriptor: DescriptorBase): + # When + descriptor.name = 'new_name' + # Then Expect + assert descriptor.name == 'new_name' + + @pytest.mark.parametrize( + 'name', + [1, True, 1.0, [], {}, (), object(), None], + ids=['int', 'bool', 'float', 'list', 'dict', 'tuple', 'object', 'None'], + ) + def test_name_setter_type_error(self, descriptor: DescriptorBase, name): + # When Then + with pytest.raises(TypeError): + descriptor.name = name + + def test_description_setter(self, descriptor: DescriptorBase): + # When + descriptor.description = 'new_description' + # Then Expect + assert descriptor.description == 'new_description' + + @pytest.mark.parametrize( + 'description', + [1, True, 1.0, [], {}, (), object()], + ids=['int', 'bool', 'float', 'list', 'dict', 'tuple', 'object'], + ) + def test_description_setter_type_error(self, descriptor: DescriptorBase, description): + # When Then + with pytest.raises(TypeError): + descriptor.description = description + + def test_url_setter(self, descriptor: DescriptorBase): + # When + descriptor.url = 'new_url' + # Then Expect + assert descriptor.url == 'new_url' + + @pytest.mark.parametrize( + 'url', + [1, True, 1.0, [], {}, (), object()], + ids=['int', 'bool', 'float', 'list', 'dict', 'tuple', 'object'], + ) + def test_url_setter_type_error(self, descriptor: DescriptorBase, url): + # When Then + with pytest.raises(TypeError): + descriptor.url = url + + @pytest.mark.parametrize('stack_enabled,stack_elements', [(False, 0), (True, 1)]) + def test_set_display_name_without_global_object_stack( + self, descriptor: DescriptorBase, stack_enabled, stack_elements + ): + # When + descriptor.__repr__ = lambda x: 'DescriptorBase' + global_object.stack.clear() + global_object.stack._enabled = stack_enabled + + # Then + descriptor.display_name = 'new_display_name' + + # Expect + assert descriptor.display_name == 'new_display_name' + assert len(global_object.stack.history) == stack_elements + + def test_copy(self, descriptor: DescriptorBase): + # When Then + descriptor_copy = descriptor.__copy__() + + # Expect + assert type(descriptor_copy) == DescriptorBase + assert descriptor_copy._name == descriptor._name + assert descriptor_copy._description == descriptor._description + assert descriptor_copy._url == descriptor._url + assert descriptor_copy._display_name == descriptor._display_name + + def test_unique_name_generator(self, clear, descriptor: DescriptorBase): + # When + second_descriptor = DescriptorBase(name='test', unique_name='DescriptorBase_2') + + # Then + third_descriptor = DescriptorBase(name='test2') + fourth_descriptor = DescriptorBase(name='test3') + + # Expect + assert descriptor.unique_name == 'DescriptorBase_0' + assert third_descriptor.unique_name == 'DescriptorBase_3' + assert fourth_descriptor.unique_name == 'DescriptorBase_4' + + def test_unique_name_change(self, clear, descriptor: DescriptorBase): + # When Then + descriptor.unique_name = 'test' + # Expect + assert descriptor.unique_name == 'test' + + @pytest.mark.parametrize('input', [2, 2.0, [2], {2}, None]) + def test_unique_name_change_exception(self, input, descriptor: DescriptorBase): + # When Then Expect + with pytest.raises(TypeError): + descriptor.unique_name = input diff --git a/tests/unit_tests/variable/test_descriptor_bool.py b/tests/unit/variable/test_descriptor_bool.py similarity index 69% rename from tests/unit_tests/variable/test_descriptor_bool.py rename to tests/unit/variable/test_descriptor_bool.py index 4be20657..3c181f0e 100644 --- a/tests/unit_tests/variable/test_descriptor_bool.py +++ b/tests/unit/variable/test_descriptor_bool.py @@ -1,21 +1,25 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import pytest -from easyscience.variable import DescriptorBool from easyscience import global_object +from easyscience.variable import DescriptorBool + class TestDescriptorBool: @pytest.fixture def descriptor(self): descriptor = DescriptorBool( - name="name", + name='name', value=True, - description="description", - url="url", - display_name="display_name", + description='description', + url='url', + display_name='display_name', parent=None, ) return descriptor - + @pytest.fixture def clear(self): global_object.map._clear() @@ -25,22 +29,22 @@ def test_init(self, descriptor: DescriptorBool): assert descriptor._bool_value == True # From super - assert descriptor._name == "name" - assert descriptor._description == "description" - assert descriptor._url == "url" - assert descriptor._display_name == "display_name" + assert descriptor._name == 'name' + assert descriptor._description == 'description' + assert descriptor._url == 'url' + assert descriptor._display_name == 'display_name' - @pytest.mark.parametrize("bool_value", ["string", 0, 1.0]) + @pytest.mark.parametrize('bool_value', ['string', 0, 1.0]) def test_init_bool_value_type_exception(self, bool_value): # When Then Expect with pytest.raises(ValueError): DescriptorBool( - name="name", + name='name', value=bool_value, - description="description", - url="url", - display_name="display_name", + description='description', + url='url', + display_name='display_name', parent=None, ) @@ -55,7 +59,7 @@ def test_set_value(self, descriptor: DescriptorBool): # Expect assert descriptor._bool_value == False - @pytest.mark.parametrize("bool_value", ["string", 0, 0.0]) + @pytest.mark.parametrize('bool_value', ['string', 0, 0.0]) def test_set_value_type_exception(self, descriptor: DescriptorBool, bool_value): # When Then Expect with pytest.raises(TypeError): @@ -74,4 +78,4 @@ def test_copy(self, descriptor: DescriptorBool): # Expect assert type(descriptor_copy) == DescriptorBool - assert descriptor_copy._bool_value == descriptor._bool_value \ No newline at end of file + assert descriptor_copy._bool_value == descriptor._bool_value diff --git a/tests/unit_tests/variable/test_descriptor_number.py b/tests/unit/variable/test_descriptor_number.py similarity index 58% rename from tests/unit_tests/variable/test_descriptor_number.py rename to tests/unit/variable/test_descriptor_number.py index 5dc4e060..6abd3029 100644 --- a/tests/unit_tests/variable/test_descriptor_number.py +++ b/tests/unit/variable/test_descriptor_number.py @@ -1,22 +1,25 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import pytest -from unittest.mock import MagicMock import scipp as sc from scipp import UnitError from easyscience import DescriptorNumber from easyscience import global_object + class TestDescriptorNumber: @pytest.fixture def descriptor(self): descriptor = DescriptorNumber( - name="name", + name='name', value=1, - unit="m", + unit='m', variance=0.1, - description="description", - url="url", - display_name="display_name", + description='description', + url='url', + display_name='display_name', parent=None, ) return descriptor @@ -28,79 +31,79 @@ def clear(self): def test_init(self, descriptor: DescriptorNumber): # When Then Expect assert descriptor._scalar.value == 1 - assert descriptor._scalar.unit == "m" + assert descriptor._scalar.unit == 'm' assert descriptor._scalar.variance == 0.1 assert descriptor._observers == [] # From super - assert descriptor._name == "name" - assert descriptor._description == "description" - assert descriptor._url == "url" - assert descriptor._display_name == "display_name" + assert descriptor._name == 'name' + assert descriptor._description == 'description' + assert descriptor._url == 'url' + assert descriptor._display_name == 'display_name' def test_init_sc_unit(self): # When Then descriptor = DescriptorNumber( - name="name", + name='name', value=1, - unit=sc.units.Unit("m"), + unit=sc.units.Unit('m'), variance=0.1, - description="description", - url="url", - display_name="display_name", + description='description', + url='url', + display_name='display_name', parent=None, ) # Expect assert descriptor._scalar.value == 1 - assert descriptor._scalar.unit == "m" + assert descriptor._scalar.unit == 'm' assert descriptor._scalar.variance == 0.1 def test_init_sc_unit_unknown(self): # When Then Expect with pytest.raises(UnitError): DescriptorNumber( - name="name", + name='name', value=1, - unit="unknown", + unit='unknown', variance=0.1, - description="description", - url="url", - display_name="display_name", + description='description', + url='url', + display_name='display_name', parent=None, ) - @pytest.mark.parametrize("value", [True, "string"]) + @pytest.mark.parametrize('value', [True, 'string']) def test_init_value_type_exception(self, value): - # When + # When # Then Expect with pytest.raises(TypeError): DescriptorNumber( - name="name", + name='name', value=value, - unit="m", + unit='m', variance=0.1, - description="description", - url="url", - display_name="display_name", + description='description', + url='url', + display_name='display_name', parent=None, ) def test_init_variance_exception(self): - # When + # When variance = -1 # Then Expect with pytest.raises(ValueError): DescriptorNumber( - name="name", + name='name', value=1, - unit="m", + unit='m', variance=variance, - description="description", - url="url", - display_name="display_name", + description='description', + url='url', + display_name='display_name', parent=None, ) @@ -110,23 +113,33 @@ def test_from_scipp(self): full_value = sc.scalar(1, unit='m') # Then - descriptor = DescriptorNumber.from_scipp(name="name", full_value=full_value) + descriptor = DescriptorNumber.from_scipp(name='name', full_value=full_value) # Expect assert descriptor._scalar.value == 1 - assert descriptor._scalar.unit == "m" + assert descriptor._scalar.unit == 'm' assert descriptor._scalar.variance == None - @pytest.mark.parametrize("full_value", [sc.array(values=[1,2], dims=["x"]), sc.array(values=[[1], [2]], dims=["x","y"]), object(), 1, "string"], ids=["1D", "2D", "object", "int", "string"]) + @pytest.mark.parametrize( + 'full_value', + [ + sc.array(values=[1, 2], dims=['x']), + sc.array(values=[[1], [2]], dims=['x', 'y']), + object(), + 1, + 'string', + ], + ids=['1D', '2D', 'object', 'int', 'string'], + ) def test_from_scipp_type_exception(self, full_value): # When Then Expect with pytest.raises(TypeError): - DescriptorNumber.from_scipp(name="name", full_value=full_value) + DescriptorNumber.from_scipp(name='name', full_value=full_value) def test_full_value(self, descriptor: DescriptorNumber): # When Then Expect assert descriptor.full_value == sc.scalar(1, unit='m') - + def test_set_full_value(self, descriptor: DescriptorNumber): with pytest.raises(AttributeError): descriptor.full_value = sc.scalar(2, unit='s') @@ -134,7 +147,7 @@ def test_set_full_value(self, descriptor: DescriptorNumber): def test_unit(self, descriptor: DescriptorNumber): # When Then Expect assert descriptor.unit == 'm' - + def test_set_unit(self, descriptor: DescriptorNumber): with pytest.raises(AttributeError): descriptor.unit = 's' @@ -151,7 +164,7 @@ def test_convert_unit(self, descriptor: DescriptorNumber): def test_variance(self, descriptor: DescriptorNumber): # When Then Expect assert descriptor.variance == 0.1 - + def test_set_variance(self, descriptor: DescriptorNumber): # When Then descriptor.variance = 0.2 @@ -163,7 +176,7 @@ def test_set_variance(self, descriptor: DescriptorNumber): def test_error(self, descriptor: DescriptorNumber): # When Then Expect assert descriptor.error == 0.31622776601683794 - + def test_set_error(self, descriptor: DescriptorNumber): # When Then descriptor.error = 0.31622776601683794 @@ -172,7 +185,6 @@ def test_set_error(self, descriptor: DescriptorNumber): assert descriptor.error == 0.31622776601683794 assert descriptor.variance == 0.1 - def test_value(self, descriptor: DescriptorNumber): # When Then Expect assert descriptor.value == 1 @@ -189,7 +201,7 @@ def test_repr(self, descriptor: DescriptorNumber): repr_str = str(descriptor) # Expect - assert repr_str == "" + assert repr_str == "" def test_copy(self, descriptor: DescriptorNumber): # When Then @@ -200,14 +212,14 @@ def test_copy(self, descriptor: DescriptorNumber): assert descriptor_copy._scalar.value == descriptor._scalar.value assert descriptor_copy._scalar.unit == descriptor._scalar.unit - @pytest.mark.parametrize("unit_string, expected", [ - ("1e+9", "dimensionless"), - ("1000", "dimensionless"), - ("10dm^2", "m^2")], - ids=["scientific_notation", "numbers", "unit_prefix"]) + @pytest.mark.parametrize( + 'unit_string, expected', + [('1e+9', 'dimensionless'), ('1000', 'dimensionless'), ('10dm^2', 'm^2')], + ids=['scientific_notation', 'numbers', 'unit_prefix'], + ) def test_base_unit(self, unit_string, expected): # When - descriptor = DescriptorNumber(name="name", value=1, unit=unit_string) + descriptor = DescriptorNumber(name='name', value=1, unit=unit_string) # Then base_unit = descriptor._base_unit() @@ -215,10 +227,25 @@ def test_base_unit(self, unit_string, expected): # Expect assert base_unit == expected - @pytest.mark.parametrize("test, expected", [ - (DescriptorNumber("test", 2, "m", 0.01,), DescriptorNumber("test + name", 3, "m", 0.11)), - (DescriptorNumber("test", 2, "cm", 0.01), DescriptorNumber("test + name", 102, "cm", 1000.01))], - ids=["regular", "unit_conversion"]) + @pytest.mark.parametrize( + 'test, expected', + [ + ( + DescriptorNumber( + 'test', + 2, + 'm', + 0.01, + ), + DescriptorNumber('test + name', 3, 'm', 0.11), + ), + ( + DescriptorNumber('test', 2, 'cm', 0.01), + DescriptorNumber('test + name', 102, 'cm', 1000.01), + ), + ], + ids=['regular', 'unit_conversion'], + ) def test_addition(self, descriptor: DescriptorNumber, test, expected): # When Then result = test + descriptor @@ -229,12 +256,12 @@ def test_addition(self, descriptor: DescriptorNumber, test, expected): assert result.value == expected.value assert result.unit == expected.unit assert result.variance == expected.variance - + assert descriptor.unit == 'm' def test_addition_with_scalar(self): - # When - descriptor = DescriptorNumber(name="name", value=1, variance=0.1) + # When + descriptor = DescriptorNumber(name='name', value=1, variance=0.1) # Then result = descriptor + 1.0 @@ -244,27 +271,53 @@ def test_addition_with_scalar(self): assert type(result) == DescriptorNumber assert result.name == result.unique_name assert result.value == 2.0 - assert result.unit == "dimensionless" + assert result.unit == 'dimensionless' assert result.variance == 0.1 assert type(result_reverse) == DescriptorNumber assert result_reverse.name == result_reverse.unique_name assert result_reverse.value == 2.0 - assert result_reverse.unit == "dimensionless" + assert result_reverse.unit == 'dimensionless' assert result_reverse.variance == 0.1 - @pytest.mark.parametrize("test", [1.0, DescriptorNumber("test", 2, "s",)], ids=["add_scalar_to_unit", "incompatible_units"]) + @pytest.mark.parametrize( + 'test', + [ + 1.0, + DescriptorNumber( + 'test', + 2, + 's', + ), + ], + ids=['add_scalar_to_unit', 'incompatible_units'], + ) def test_addition_exception(self, descriptor: DescriptorNumber, test): # When Then Expect with pytest.raises(UnitError): result = descriptor + test with pytest.raises(UnitError): result_reverse = test + descriptor - - @pytest.mark.parametrize("test, expected", [ - (DescriptorNumber("test", 2, "m", 0.01,), DescriptorNumber("test - name", 1, "m", 0.11)), - (DescriptorNumber("test", 2, "cm", 0.01), DescriptorNumber("test - name", -98, "cm", 1000.01))], - ids=["regular", "unit_conversion"]) + + @pytest.mark.parametrize( + 'test, expected', + [ + ( + DescriptorNumber( + 'test', + 2, + 'm', + 0.01, + ), + DescriptorNumber('test - name', 1, 'm', 0.11), + ), + ( + DescriptorNumber('test', 2, 'cm', 0.01), + DescriptorNumber('test - name', -98, 'cm', 1000.01), + ), + ], + ids=['regular', 'unit_conversion'], + ) def test_subtraction(self, descriptor: DescriptorNumber, test, expected): # When Then result = test - descriptor @@ -279,8 +332,8 @@ def test_subtraction(self, descriptor: DescriptorNumber, test, expected): assert descriptor.unit == 'm' def test_subtraction_with_scalar(self): - # When - descriptor = DescriptorNumber(name="name", value=2, variance=0.1) + # When + descriptor = DescriptorNumber(name='name', value=2, variance=0.1) # Then result = descriptor - 1.0 @@ -290,16 +343,27 @@ def test_subtraction_with_scalar(self): assert type(result) == DescriptorNumber assert result.name == result.unique_name assert result.value == 1.0 - assert result.unit == "dimensionless" + assert result.unit == 'dimensionless' assert result.variance == 0.1 assert type(result_reverse) == DescriptorNumber assert result_reverse.name == result_reverse.unique_name assert result_reverse.value == -1.0 - assert result_reverse.unit == "dimensionless" + assert result_reverse.unit == 'dimensionless' assert result_reverse.variance == 0.1 - @pytest.mark.parametrize("test", [1.0, DescriptorNumber("test", 2, "s",)], ids=["sub_scalar_to_unit", "incompatible_units"]) + @pytest.mark.parametrize( + 'test', + [ + 1.0, + DescriptorNumber( + 'test', + 2, + 's', + ), + ], + ids=['sub_scalar_to_unit', 'incompatible_units'], + ) def test_subtraction_exception(self, descriptor: DescriptorNumber, test): # When Then Expect with pytest.raises(UnitError): @@ -307,10 +371,25 @@ def test_subtraction_exception(self, descriptor: DescriptorNumber, test): with pytest.raises(UnitError): result_reverse = descriptor - test - @pytest.mark.parametrize("test, expected", [ - (DescriptorNumber("test", 2, "m", 0.01,), DescriptorNumber("test * name", 2, "m^2", 0.41)), - (DescriptorNumber("test", 2, "dm", 0.01), DescriptorNumber("test * name", 0.2, "m^2", 0.0041))], - ids=["regular", "base_unit_conversion"]) + @pytest.mark.parametrize( + 'test, expected', + [ + ( + DescriptorNumber( + 'test', + 2, + 'm', + 0.01, + ), + DescriptorNumber('test * name', 2, 'm^2', 0.41), + ), + ( + DescriptorNumber('test', 2, 'dm', 0.01), + DescriptorNumber('test * name', 0.2, 'm^2', 0.0041), + ), + ], + ids=['regular', 'base_unit_conversion'], + ) def test_multiplication(self, descriptor: DescriptorNumber, test, expected): # When Then result = test * descriptor @@ -331,19 +410,36 @@ def test_multiplication_with_scalar(self, descriptor: DescriptorNumber): assert type(result) == DescriptorNumber assert result.name == result.unique_name assert result.value == 2.0 - assert result.unit == "m" + assert result.unit == 'm' assert result.variance == 0.4 assert type(result_reverse) == DescriptorNumber assert result_reverse.name == result_reverse.unique_name assert result_reverse.value == 2.0 - assert result_reverse.unit == "m" + assert result_reverse.unit == 'm' assert result_reverse.variance == 0.4 - @pytest.mark.parametrize("test, expected, expected_reverse", [ - (DescriptorNumber("test", 2, "m^2", 0.01,), DescriptorNumber("name / test", 0.5, "1/m", 0.025625), DescriptorNumber("test / name", 2, "m", 0.41)), - (2, DescriptorNumber("name / 2", 0.5, "m", 0.025), DescriptorNumber("2 / name", 2, "1/m", 0.4))], - ids=["descriptorNumber", "scalar"]) + @pytest.mark.parametrize( + 'test, expected, expected_reverse', + [ + ( + DescriptorNumber( + 'test', + 2, + 'm^2', + 0.01, + ), + DescriptorNumber('name / test', 0.5, '1/m', 0.025625), + DescriptorNumber('test / name', 2, 'm', 0.41), + ), + ( + 2, + DescriptorNumber('name / 2', 0.5, 'm', 0.025), + DescriptorNumber('2 / name', 2, '1/m', 0.4), + ), + ], + ids=['descriptorNumber', 'scalar'], + ) def test_division(self, descriptor: DescriptorNumber, test, expected, expected_reverse): # When Then result = descriptor / test @@ -362,31 +458,40 @@ def test_division(self, descriptor: DescriptorNumber, test, expected, expected_r assert result_reverse.unit == expected_reverse.unit assert result_reverse.variance == pytest.approx(expected_reverse.variance) - @pytest.mark.parametrize("test", [0, DescriptorNumber("test", 0, "m", 0.01)], ids=["zero", "zero_descriptor"]) + @pytest.mark.parametrize( + 'test', [0, DescriptorNumber('test', 0, 'm', 0.01)], ids=['zero', 'zero_descriptor'] + ) def test_division_exception(self, descriptor: DescriptorNumber, test): # When Then Expect with pytest.raises(ZeroDivisionError): result = descriptor / test def test_division_exception_reverse(self): - # When - descriptor = DescriptorNumber(name="name", value=0, variance=0.1) + # When + descriptor = DescriptorNumber(name='name', value=0, variance=0.1) # Then Expect with pytest.raises(ZeroDivisionError): result = 2 / descriptor - @pytest.mark.parametrize("test, expected", [ - (DescriptorNumber("test", 2), DescriptorNumber("name ** test", 4, unit="m^2", variance=1.6)), - (2, DescriptorNumber("name ** 2", 4, unit="m^2", variance=1.6)), - (-2, DescriptorNumber("name ** -2", 0.25, unit="1/m^2", variance=0.00625))], - ids=["descriptorNumber", "scalar", "negative_scalar"]) + @pytest.mark.parametrize( + 'test, expected', + [ + ( + DescriptorNumber('test', 2), + DescriptorNumber('name ** test', 4, unit='m^2', variance=1.6), + ), + (2, DescriptorNumber('name ** 2', 4, unit='m^2', variance=1.6)), + (-2, DescriptorNumber('name ** -2', 0.25, unit='1/m^2', variance=0.00625)), + ], + ids=['descriptorNumber', 'scalar', 'negative_scalar'], + ) def test_power_of_descriptor(self, test, expected): - # When - descriptor = DescriptorNumber(name="name", value=2, unit="m", variance=0.1) + # When + descriptor = DescriptorNumber(name='name', value=2, unit='m', variance=0.1) # Then - result = descriptor ** test + result = descriptor**test # Expect assert type(result) == DescriptorNumber @@ -396,53 +501,65 @@ def test_power_of_descriptor(self, test, expected): assert result.variance == expected.variance def test_power_of_dimensionless_descriptor(self): - # When - descriptor = DescriptorNumber(name="name", value=2, unit="dimensionless", variance=0.1) + # When + descriptor = DescriptorNumber(name='name', value=2, unit='dimensionless', variance=0.1) # Then - result = descriptor ** 0.5 + result = descriptor**0.5 # Expect assert type(result) == DescriptorNumber assert result.name == result.unique_name assert result.value == 1.4142135623730951 - assert result.unit == "dimensionless" + assert result.unit == 'dimensionless' assert result.variance == pytest.approx(0.0125) - @pytest.mark.parametrize("descriptor, exponent, exception", [ - (DescriptorNumber("name", 2), DescriptorNumber("test", 2, unit="m"), UnitError), - (DescriptorNumber("name", 2), DescriptorNumber("test", 2, variance=0.1), ValueError), - (DescriptorNumber("name", 2, unit="m"), 0.5, UnitError), - (DescriptorNumber("name", -2), 0.5, ValueError)], - ids=["descriptor_unit", "descriptor_variance", "fractional_of_unit", "fractonal_of_negative"]) + @pytest.mark.parametrize( + 'descriptor, exponent, exception', + [ + (DescriptorNumber('name', 2), DescriptorNumber('test', 2, unit='m'), UnitError), + (DescriptorNumber('name', 2), DescriptorNumber('test', 2, variance=0.1), ValueError), + (DescriptorNumber('name', 2, unit='m'), 0.5, UnitError), + (DescriptorNumber('name', -2), 0.5, ValueError), + ], + ids=[ + 'descriptor_unit', + 'descriptor_variance', + 'fractional_of_unit', + 'fractonal_of_negative', + ], + ) def test_power_of_descriptor_exceptions(self, descriptor, exponent, exception): # When Then Expect with pytest.raises(exception): - result = descriptor ** exponent - + result = descriptor**exponent def test_descriptor_as_exponentiation(self): - # When - descriptor = DescriptorNumber(name="name", value=2) + # When + descriptor = DescriptorNumber(name='name', value=2) # Then - result = 2 ** descriptor + result = 2**descriptor # Expect assert result == 4 - @pytest.mark.parametrize("exponent, exception", [ - (DescriptorNumber("test", 2, unit="m"), UnitError), - (DescriptorNumber("test", 2, variance=0.1), ValueError)], - ids=["descriptor_unit", "descriptor_variance"]) + @pytest.mark.parametrize( + 'exponent, exception', + [ + (DescriptorNumber('test', 2, unit='m'), UnitError), + (DescriptorNumber('test', 2, variance=0.1), ValueError), + ], + ids=['descriptor_unit', 'descriptor_variance'], + ) def test_descriptor_as_exponentiation_exception(self, exponent, exception): # When Then Expect with pytest.raises(exception): - result = 2 ** exponent + result = 2**exponent def test_negation(self): - # When - descriptor = DescriptorNumber(name="name", unit="m", value=2, variance=0.1) + # When + descriptor = DescriptorNumber(name='name', unit='m', value=2, variance=0.1) # Then result = -descriptor @@ -451,12 +568,12 @@ def test_negation(self): assert type(result) == DescriptorNumber assert result.name == result.unique_name assert result.value == -2 - assert result.unit == "m" + assert result.unit == 'm' assert result.variance == 0.1 def test_abs(self): - # When - descriptor = DescriptorNumber(name="name", unit="m", value=-2, variance=0.1) + # When + descriptor = DescriptorNumber(name='name', unit='m', value=-2, variance=0.1) # Then result = abs(descriptor) @@ -465,5 +582,5 @@ def test_abs(self): assert type(result) == DescriptorNumber assert result.name == result.unique_name assert result.value == 2 - assert result.unit == "m" - assert result.variance == 0.1 \ No newline at end of file + assert result.unit == 'm' + assert result.variance == 0.1 diff --git a/tests/unit_tests/variable/test_descriptor_str.py b/tests/unit/variable/test_descriptor_str.py similarity index 59% rename from tests/unit_tests/variable/test_descriptor_str.py rename to tests/unit/variable/test_descriptor_str.py index aa593ed9..46acc847 100644 --- a/tests/unit_tests/variable/test_descriptor_str.py +++ b/tests/unit/variable/test_descriptor_str.py @@ -1,60 +1,64 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import pytest -from easyscience.variable import DescriptorStr from easyscience import global_object +from easyscience.variable import DescriptorStr + class TestDescriptorStr: @pytest.fixture def descriptor(self): descriptor = DescriptorStr( - name="name", - value="string", - description="description", - url="url", - display_name="display_name", + name='name', + value='string', + description='description', + url='url', + display_name='display_name', parent=None, ) return descriptor - + @pytest.fixture def clear(self): global_object.map._clear() def test_init(self, descriptor: DescriptorStr): # When Then Expect - assert descriptor._string == "string" + assert descriptor._string == 'string' # From super - assert descriptor._name == "name" - assert descriptor._description == "description" - assert descriptor._url == "url" - assert descriptor._display_name == "display_name" + assert descriptor._name == 'name' + assert descriptor._description == 'description' + assert descriptor._url == 'url' + assert descriptor._display_name == 'display_name' - @pytest.mark.parametrize("string", [True, 0, 1.0]) + @pytest.mark.parametrize('string', [True, 0, 1.0]) def test_init_string_type_exception(self, string): # When Then Expect with pytest.raises(ValueError): DescriptorStr( - name="name", + name='name', value=string, - description="description", - url="url", - display_name="display_name", + description='description', + url='url', + display_name='display_name', parent=None, ) def test_value(self, descriptor: DescriptorStr): # When Then Expect - assert descriptor.value == "string" + assert descriptor.value == 'string' def test_set_value(self, descriptor: DescriptorStr): # When Then - descriptor.value = "new_string" + descriptor.value = 'new_string' # Expect - assert descriptor._string == "new_string" + assert descriptor._string == 'new_string' - @pytest.mark.parametrize("string", [True, 0, 1.0]) + @pytest.mark.parametrize('string', [True, 0, 1.0]) def test_set_value_type_exception(self, descriptor: DescriptorStr, string): # When Then Expect with pytest.raises(ValueError): @@ -73,4 +77,4 @@ def test_copy(self, descriptor: DescriptorStr): # Expect assert type(descriptor_copy) == DescriptorStr - assert descriptor_copy._string == descriptor._string \ No newline at end of file + assert descriptor_copy._string == descriptor._string diff --git a/tests/unit_tests/variable/test_parameter.py b/tests/unit/variable/test_parameter.py similarity index 64% rename from tests/unit_tests/variable/test_parameter.py rename to tests/unit/variable/test_parameter.py index f2b756eb..87c1ce4f 100644 --- a/tests/unit_tests/variable/test_parameter.py +++ b/tests/unit/variable/test_parameter.py @@ -1,14 +1,17 @@ -import pytest +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + from unittest.mock import MagicMock -import scipp as sc -import numpy as np +import numpy as np +import pytest +import scipp as sc from scipp import UnitError -from easyscience import Parameter from easyscience import DescriptorNumber -from easyscience import global_object from easyscience import ObjBase +from easyscience import Parameter +from easyscience import global_object class TestParameter: @@ -16,15 +19,15 @@ class TestParameter: def parameter(self) -> Parameter: self.mock_callback = MagicMock() parameter = Parameter( - name="name", + name='name', value=1, - unit="m", + unit='m', variance=0.01, min=0, max=10, - description="description", - url="url", - display_name="display_name", + description='description', + url='url', + display_name='display_name', callback=self.mock_callback, parent=None, ) @@ -33,9 +36,9 @@ def parameter(self) -> Parameter: @pytest.fixture def normal_parameter(self) -> Parameter: parameter = Parameter( - name="name", + name='name', value=1, - unit="m", + unit='m', variance=0.01, min=0, max=10, @@ -58,20 +61,20 @@ def compare_parameters(self, parameter1: Parameter, parameter2: Parameter): def test_init(self, parameter: Parameter): # When Then Expect assert parameter._min.value == 0 - assert parameter._min.unit == "m" + assert parameter._min.unit == 'm' assert parameter._max.value == 10 - assert parameter._max.unit == "m" + assert parameter._max.unit == 'm' assert parameter._callback == self.mock_callback assert parameter._independent == True # From super assert parameter._scalar.value == 1 - assert parameter._scalar.unit == "m" + assert parameter._scalar.unit == 'm' assert parameter._scalar.variance == 0.01 - assert parameter._name == "name" - assert parameter._description == "description" - assert parameter._url == "url" - assert parameter._display_name == "display_name" + assert parameter._name == 'name' + assert parameter._description == 'description' + assert parameter._url == 'url' + assert parameter._display_name == 'display_name' assert parameter._fixed == False assert parameter._observers == [] @@ -83,15 +86,15 @@ def test_init_value_min_exception(self): # Then Expect with pytest.raises(ValueError): Parameter( - name="name", + name='name', value=value, - unit="m", + unit='m', variance=0.01, min=0, max=10, - description="description", - url="url", - display_name="display_name", + description='description', + url='url', + display_name='display_name', callback=mock_callback, parent=None, ) @@ -104,15 +107,15 @@ def test_init_value_max_exception(self): # Then Expect with pytest.raises(ValueError): Parameter( - name="name", + name='name', value=value, - unit="m", + unit='m', variance=0.01, min=0, max=10, - description="description", - url="url", - display_name="display_name", + description='description', + url='url', + display_name='display_name', callback=mock_callback, parent=None, ) @@ -120,18 +123,18 @@ def test_init_value_max_exception(self): def test_make_dependent_on(self, normal_parameter: Parameter): # When independent_parameter = Parameter( - name="independent", value=1, unit="m", variance=0.01, min=0, max=10 + name='independent', value=1, unit='m', variance=0.01, min=0, max=10 ) # Then normal_parameter.make_dependent_on( - dependency_expression="2*a", dependency_map={"a": independent_parameter} + dependency_expression='2*a', dependency_map={'a': independent_parameter} ) # Expect assert normal_parameter._independent == False - assert normal_parameter.dependency_expression == "2*a" - assert normal_parameter.dependency_map == {"a": independent_parameter} + assert normal_parameter.dependency_expression == '2*a' + assert normal_parameter.dependency_map == {'a': independent_parameter} self.compare_parameters(normal_parameter, 2 * independent_parameter) # Then @@ -146,95 +149,95 @@ def test_dependent_parameter_make_dependent_on_with_desired_unit( ): # When independent_parameter = Parameter( - name="independent", value=1, unit="m", variance=0.01, min=0, max=10 + name='independent', value=1, unit='m', variance=0.01, min=0, max=10 ) # Then normal_parameter.make_dependent_on( - dependency_expression="2*a", - dependency_map={"a": independent_parameter}, - desired_unit="cm", + dependency_expression='2*a', + dependency_map={'a': independent_parameter}, + desired_unit='cm', ) # Expect assert normal_parameter._independent == False - assert normal_parameter.dependency_expression == "2*a" - assert normal_parameter.dependency_map == {"a": independent_parameter} + assert normal_parameter.dependency_expression == '2*a' + assert normal_parameter.dependency_map == {'a': independent_parameter} assert normal_parameter.value == 200 * independent_parameter.value - assert normal_parameter.unit == "cm" + assert normal_parameter.unit == 'cm' assert ( normal_parameter.variance == independent_parameter.variance * 4 * 10000 ) # unit conversion from m to cm squared assert normal_parameter.min == 200 * independent_parameter.min assert normal_parameter.max == 200 * independent_parameter.max - assert normal_parameter._min.unit == "cm" - assert normal_parameter._max.unit == "cm" + assert normal_parameter._min.unit == 'cm' + assert normal_parameter._max.unit == 'cm' # Then independent_parameter.value = 2 # Expect assert normal_parameter.value == 200 * independent_parameter.value - assert normal_parameter.unit == "cm" + assert normal_parameter.unit == 'cm' assert ( normal_parameter.variance == independent_parameter.variance * 4 * 10000 ) # unit conversion from m to cm squared assert normal_parameter.min == 200 * independent_parameter.min assert normal_parameter.max == 200 * independent_parameter.max - assert normal_parameter._min.unit == "cm" - assert normal_parameter._max.unit == "cm" + assert normal_parameter._min.unit == 'cm' + assert normal_parameter._max.unit == 'cm' # Then # Change the dependency expression and unit again normal_parameter.make_dependent_on( - dependency_expression="3*a", - dependency_map={"a": independent_parameter}, - desired_unit="mm", + dependency_expression='3*a', + dependency_map={'a': independent_parameter}, + desired_unit='mm', ) # Expect assert normal_parameter._independent == False - assert normal_parameter.dependency_expression == "3*a" - assert normal_parameter.dependency_map == {"a": independent_parameter} + assert normal_parameter.dependency_expression == '3*a' + assert normal_parameter.dependency_map == {'a': independent_parameter} assert normal_parameter.value == 3000 * independent_parameter.value - assert normal_parameter.unit == "mm" + assert normal_parameter.unit == 'mm' assert ( normal_parameter.variance == independent_parameter.variance * 9 * 1000000 ) # unit conversion from m to mm squared assert normal_parameter.min == 3000 * independent_parameter.min assert normal_parameter.max == 3000 * independent_parameter.max - assert normal_parameter._min.unit == "mm" - assert normal_parameter._max.unit == "mm" + assert normal_parameter._min.unit == 'mm' + assert normal_parameter._max.unit == 'mm' # Then independent_parameter.value = 2 # Expect assert normal_parameter.value == 3000 * independent_parameter.value - assert normal_parameter.unit == "mm" + assert normal_parameter.unit == 'mm' assert ( normal_parameter.variance == independent_parameter.variance * 9 * 1000000 ) # unit conversion from m to mm squared assert normal_parameter.min == 3000 * independent_parameter.min assert normal_parameter.max == 3000 * independent_parameter.max - assert normal_parameter._min.unit == "mm" - assert normal_parameter._max.unit == "mm" + assert normal_parameter._min.unit == 'mm' + assert normal_parameter._max.unit == 'mm' def test_dependent_parameter_make_dependent_on_with_desired_unit_incompatible_unit_raises( self, normal_parameter: Parameter ): # When independent_parameter = Parameter( - name="independent", value=1, unit="m", variance=0.01, min=0, max=10 + name='independent', value=1, unit='m', variance=0.01, min=0, max=10 ) # Then Expect - with pytest.raises(UnitError, match="Failed to convert unit from m to s."): + with pytest.raises(UnitError, match='Failed to convert unit from m to s.'): normal_parameter.make_dependent_on( - dependency_expression="2*a", - dependency_map={"a": independent_parameter}, - desired_unit="s", + dependency_expression='2*a', + dependency_map={'a': independent_parameter}, + desired_unit='s', ) def test_dependent_parameter_make_dependent_on_with_incorrect_unit_raises( @@ -242,34 +245,34 @@ def test_dependent_parameter_make_dependent_on_with_incorrect_unit_raises( ): # When independent_parameter = Parameter( - name="independent", value=1, unit="m", variance=0.01, min=0, max=10 + name='independent', value=1, unit='m', variance=0.01, min=0, max=10 ) # Then Expect with pytest.raises( - TypeError, match="`desired_unit` must be a string representing a valid unit" + TypeError, match='`desired_unit` must be a string representing a valid unit' ): normal_parameter.make_dependent_on( - dependency_expression="2*a", - dependency_map={"a": independent_parameter}, + dependency_expression='2*a', + dependency_map={'a': independent_parameter}, desired_unit=123, ) def test_parameter_from_dependency(self, normal_parameter: Parameter): # When Then dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, - display_name="display_name", + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, + display_name='display_name', ) # Expect assert dependent_parameter._independent == False - assert dependent_parameter.dependency_expression == "2*a" - assert dependent_parameter.dependency_map == {"a": normal_parameter} - assert dependent_parameter.name == "dependent" - assert dependent_parameter.display_name == "display_name" + assert dependent_parameter.dependency_expression == '2*a' + assert dependent_parameter.dependency_map == {'a': normal_parameter} + assert dependent_parameter.name == 'dependent' + assert dependent_parameter.display_name == 'display_name' self.compare_parameters(dependent_parameter, 2 * normal_parameter) # Then @@ -278,48 +281,46 @@ def test_parameter_from_dependency(self, normal_parameter: Parameter): # Expect self.compare_parameters(dependent_parameter, 2 * normal_parameter) - def test_parameter_from_dependency_with_desired_unit( - self, normal_parameter: Parameter - ): + def test_parameter_from_dependency_with_desired_unit(self, normal_parameter: Parameter): # When Then dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, - display_name="display_name", - desired_unit="cm", + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, + display_name='display_name', + desired_unit='cm', ) # Expect assert dependent_parameter._independent == False - assert dependent_parameter.dependency_expression == "2*a" - assert dependent_parameter.dependency_map == {"a": normal_parameter} - assert dependent_parameter.name == "dependent" - assert dependent_parameter.display_name == "display_name" + assert dependent_parameter.dependency_expression == '2*a' + assert dependent_parameter.dependency_map == {'a': normal_parameter} + assert dependent_parameter.name == 'dependent' + assert dependent_parameter.display_name == 'display_name' assert dependent_parameter.value == 200 * normal_parameter.value - assert dependent_parameter.unit == "cm" + assert dependent_parameter.unit == 'cm' assert ( dependent_parameter.variance == normal_parameter.variance * 4 * 10000 ) # unit conversion from m to cm squared assert dependent_parameter.min == 200 * normal_parameter.min assert dependent_parameter.max == 200 * normal_parameter.max - assert dependent_parameter._min.unit == "cm" - assert dependent_parameter._max.unit == "cm" + assert dependent_parameter._min.unit == 'cm' + assert dependent_parameter._max.unit == 'cm' # Then normal_parameter.value = 2 # Expect assert dependent_parameter.value == 200 * normal_parameter.value - assert dependent_parameter.unit == "cm" + assert dependent_parameter.unit == 'cm' assert ( dependent_parameter.variance == normal_parameter.variance * 4 * 10000 ) # unit conversion from m to cm squared assert dependent_parameter.min == 200 * normal_parameter.min assert dependent_parameter.max == 200 * normal_parameter.max - assert dependent_parameter._min.unit == "cm" - assert dependent_parameter._max.unit == "cm" + assert dependent_parameter._min.unit == 'cm' + assert dependent_parameter._max.unit == 'cm' def test_parameter_from_dependency_with_desired_unit_incompatible_unit_raises( self, normal_parameter: Parameter @@ -327,27 +328,23 @@ def test_parameter_from_dependency_with_desired_unit_incompatible_unit_raises( # When Then Expect with pytest.raises(UnitError): dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, - display_name="display_name", - desired_unit="s", + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, + display_name='display_name', + desired_unit='s', ) - def test_dependent_parameter_with_unique_name( - self, clear, normal_parameter: Parameter - ): + def test_dependent_parameter_with_unique_name(self, clear, normal_parameter: Parameter): # When Then dependent_parameter = Parameter.from_dependency( - name="dependent", + name='dependent', dependency_expression='2*"Parameter_0"', ) # Expect assert dependent_parameter.dependency_expression == '2*"Parameter_0"' - assert dependent_parameter.dependency_map == { - "__Parameter_0__": normal_parameter - } + assert dependent_parameter.dependency_map == {'__Parameter_0__': normal_parameter} self.compare_parameters(dependent_parameter, 2 * normal_parameter) # Then @@ -361,48 +358,44 @@ def test_process_dependency_unique_names_double_quotes( ): # When independent_parameter = Parameter( - name="independent", + name='independent', value=1, - unit="m", + unit='m', variance=0.01, min=0, max=10, - unique_name="Special_name", + unique_name='Special_name', ) normal_parameter._dependency_map = {} # Then - normal_parameter._process_dependency_unique_names( - dependency_expression='2*"Special_name"' - ) + normal_parameter._process_dependency_unique_names(dependency_expression='2*"Special_name"') # Expect - assert normal_parameter._dependency_map == { - "__Special_name__": independent_parameter - } - assert normal_parameter._clean_dependency_string == "2*__Special_name__" + assert normal_parameter._dependency_map == {'__Special_name__': independent_parameter} + assert normal_parameter._clean_dependency_string == '2*__Special_name__' def test_process_dependency_unique_names_single_quotes( self, clear, normal_parameter: Parameter ): # When independent_parameter = Parameter( - name="independent", + name='independent', value=1, - unit="m", + unit='m', variance=0.01, min=0, max=10, - unique_name="Special_name", + unique_name='Special_name', ) independent_parameter_2 = Parameter( - name="independent_2", + name='independent_2', value=1, - unit="m", + unit='m', variance=0.01, min=0, max=10, - unique_name="Special_name_2", + unique_name='Special_name_2', ) normal_parameter._dependency_map = {} @@ -413,13 +406,10 @@ def test_process_dependency_unique_names_single_quotes( # Expect assert normal_parameter._dependency_map == { - "__Special_name__": independent_parameter, - "__Special_name_2__": independent_parameter_2, + '__Special_name__': independent_parameter, + '__Special_name_2__': independent_parameter_2, } - assert ( - normal_parameter._clean_dependency_string - == "__Special_name__ + __Special_name_2__" - ) + assert normal_parameter._clean_dependency_string == '__Special_name__ + __Special_name_2__' def test_process_dependency_unique_names_exception_unique_name_does_not_exist( self, clear, normal_parameter: Parameter @@ -430,7 +420,7 @@ def test_process_dependency_unique_names_exception_unique_name_does_not_exist( # Then Expect with pytest.raises( ValueError, - match="A Parameter with unique_name Special_name does not exist. Please check your dependency expression.", + match='A Parameter with unique_name Special_name does not exist. Please check your dependency expression.', ): normal_parameter._process_dependency_unique_names( dependency_expression='2*"Special_name"' @@ -441,30 +431,28 @@ def test_process_dependency_unique_names_exception_not_a_descriptorNumber( ): # When normal_parameter._dependency_map = {} - base_obj = ObjBase(name="ObjBase", unique_name="base_obj") + base_obj = ObjBase(name='ObjBase', unique_name='base_obj') # Then Expect with pytest.raises( ValueError, - match="The object with unique_name base_obj is not a Parameter or DescriptorNumber. Please check your dependency expression.", + match='The object with unique_name base_obj is not a Parameter or DescriptorNumber. Please check your dependency expression.', ): - normal_parameter._process_dependency_unique_names( - dependency_expression='2*"base_obj"' - ) + normal_parameter._process_dependency_unique_names(dependency_expression='2*"base_obj"') @pytest.mark.parametrize( - "dependency_expression, dependency_map", + 'dependency_expression, dependency_map', [ - (2, {"a": Parameter(name="a", value=1)}), - ("2*a", ["a", Parameter(name="a", value=1)]), - ("2*a", {4: Parameter(name="a", value=1)}), - ("2*a", {"a": ObjBase(name="a")}), + (2, {'a': Parameter(name='a', value=1)}), + ('2*a', ['a', Parameter(name='a', value=1)]), + ('2*a', {4: Parameter(name='a', value=1)}), + ('2*a', {'a': ObjBase(name='a')}), ], ids=[ - "dependency_expression_not_a_string", - "dependency_map_not_a_dict", - "dependency_map_keys_not_strings", - "dependency_map_values_not_descriptor_number", + 'dependency_expression_not_a_string', + 'dependency_map_not_a_dict', + 'dependency_map_keys_not_strings', + 'dependency_map_values_not_descriptor_number', ], ) def test_parameter_from_dependency_input_exceptions( @@ -473,50 +461,48 @@ def test_parameter_from_dependency_input_exceptions( # When Then Expect with pytest.raises(TypeError): Parameter.from_dependency( - name="dependent", + name='dependent', dependency_expression=dependency_expression, dependency_map=dependency_map, ) @pytest.mark.parametrize( - "dependency_expression, error", + 'dependency_expression, error', [ - ("2*a + b", NameError), - ("2*a + 3*", SyntaxError), - ("2 + 2", TypeError), + ('2*a + b', NameError), + ('2*a + 3*', SyntaxError), + ('2 + 2', TypeError), ('2*"special_name"', ValueError), ], ids=[ - "parameter_not_in_map", - "invalid_dependency_expression", - "result_not_a_descriptor_number", - "unique_name_does_not_exist", + 'parameter_not_in_map', + 'invalid_dependency_expression', + 'result_not_a_descriptor_number', + 'unique_name_does_not_exist', ], ) def test_parameter_make_dependent_on_exceptions_cleanup_previously_dependent( self, normal_parameter, dependency_expression, error ): # When - independent_parameter = Parameter( - name="independent", value=10, unit="s", variance=0.02 - ) + independent_parameter = Parameter(name='independent', value=10, unit='s', variance=0.02) dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="best", - dependency_map={"best": independent_parameter}, + name='dependent', + dependency_expression='best', + dependency_map={'best': independent_parameter}, ) # Then Expect # Check that the correct error is raised with pytest.raises(error): dependent_parameter.make_dependent_on( dependency_expression=dependency_expression, - dependency_map={"a": normal_parameter}, + dependency_map={'a': normal_parameter}, ) # Check that everything is properly cleaned up assert normal_parameter._observers == [] assert dependent_parameter.independent == False - assert dependent_parameter.dependency_expression == "best" - assert dependent_parameter.dependency_map == {"best": independent_parameter} + assert dependent_parameter.dependency_expression == 'best' + assert dependent_parameter.dependency_map == {'best': independent_parameter} independent_parameter.value = 50 self.compare_parameters(dependent_parameter, independent_parameter) @@ -524,15 +510,13 @@ def test_parameter_make_dependent_on_exceptions_cleanup_previously_independent( self, normal_parameter ): # When - independent_parameter = Parameter( - name="independent", value=10, unit="s", variance=0.02 - ) + independent_parameter = Parameter(name='independent', value=10, unit='s', variance=0.02) # Then Expect # Check that the correct error is raised with pytest.raises(NameError): independent_parameter.make_dependent_on( - dependency_expression="2*a + b", - dependency_map={"a": normal_parameter}, + dependency_expression='2*a + b', + dependency_map={'a': normal_parameter}, ) # Check that everything is properly cleaned up assert normal_parameter._observers == [] @@ -543,9 +527,9 @@ def test_parameter_make_dependent_on_exceptions_cleanup_previously_independent( def test_dependent_parameter_updates(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) # Then Expect @@ -558,7 +542,7 @@ def test_dependent_parameter_updates(self, normal_parameter: Parameter): normal_parameter.error = 0.2 self.compare_parameters(dependent_parameter, 2 * normal_parameter) - normal_parameter.convert_unit("cm") + normal_parameter.convert_unit('cm') self.compare_parameters(dependent_parameter, 2 * normal_parameter) normal_parameter.min = 1 @@ -570,19 +554,19 @@ def test_dependent_parameter_updates(self, normal_parameter: Parameter): def test_dependent_parameter_indirect_updates(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) dependent_parameter_2 = Parameter.from_dependency( - name="dependent_2", - dependency_expression="10*a", - dependency_map={"a": normal_parameter}, + name='dependent_2', + dependency_expression='10*a', + dependency_map={'a': normal_parameter}, ) dependent_parameter_3 = Parameter.from_dependency( - name="dependent_3", - dependency_expression="b+c", - dependency_map={"b": dependent_parameter, "c": dependent_parameter_2}, + name='dependent_3', + dependency_expression='b+c', + dependency_map={'b': dependent_parameter, 'c': dependent_parameter_2}, ) # Then normal_parameter.value = 2 @@ -597,20 +581,20 @@ def test_dependent_parameter_indirect_updates(self, normal_parameter: Parameter) def test_dependent_parameter_cyclic_dependencies(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) dependent_parameter_2 = Parameter.from_dependency( - name="dependent_2", - dependency_expression="2*b", - dependency_map={"b": dependent_parameter}, + name='dependent_2', + dependency_expression='2*b', + dependency_map={'b': dependent_parameter}, ) # Then Expect with pytest.raises(RuntimeError): normal_parameter.make_dependent_on( - dependency_expression="2*c", dependency_map={"c": dependent_parameter_2} + dependency_expression='2*c', dependency_map={'c': dependent_parameter_2} ) # Check that everything is properly cleaned up assert dependent_parameter_2._observers == [] @@ -622,9 +606,9 @@ def test_dependent_parameter_cyclic_dependencies(self, normal_parameter: Paramet def test_dependent_parameter_logical_dependency(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="a if a.value > 0 else -a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='a if a.value > 0 else -a', + dependency_map={'a': normal_parameter}, ) self.compare_parameters(dependent_parameter, normal_parameter) @@ -636,15 +620,13 @@ def test_dependent_parameter_logical_dependency(self, normal_parameter: Paramete def test_dependent_parameter_return_is_descriptor_number(self): # When - descriptor_number = DescriptorNumber( - name="descriptor", value=1, unit="m", variance=0.01 - ) + descriptor_number = DescriptorNumber(name='descriptor', value=1, unit='m', variance=0.01) # Then dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*descriptor", - dependency_map={"descriptor": descriptor_number}, + name='dependent', + dependency_expression='2*descriptor', + dependency_map={'descriptor': descriptor_number}, ) # Expect @@ -662,18 +644,18 @@ def test_dependent_parameter_division_expression_order(self): would work correctly. """ # When - angstrom = DescriptorNumber("angstrom", 1e-10, unit="m") + angstrom = DescriptorNumber('angstrom', 1e-10, unit='m') jump_length = Parameter( - name="jump_length", + name='jump_length', value=float(1.0), fixed=False, - unit="angstrom", + unit='angstrom', ) - expression = "jump_length / angstrom" + expression = 'jump_length / angstrom' dependency_map = { - "jump_length": jump_length, - "angstrom": angstrom, + 'jump_length': jump_length, + 'angstrom': angstrom, } # Calculate the expected result from direct division @@ -691,7 +673,7 @@ def test_dependent_parameter_division_expression_order(self): assert dependent_param.value == pytest.approx(expected_value) # Also test the alternative expression that previously worked - expression_alt = "1/angstrom * jump_length" + expression_alt = '1/angstrom * jump_length' dependent_param_alt = Parameter(name='b', value=1.0) dependent_param_alt.make_dependent_on( dependency_expression=expression_alt, @@ -702,33 +684,33 @@ def test_dependent_parameter_division_expression_order(self): def test_dependent_parameter_overwrite_dependency(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) self.compare_parameters(dependent_parameter, 2 * normal_parameter) # Then normal_parameter_2 = Parameter( - name="a2", value=-2, unit="m", variance=0.01, min=-10, max=0 + name='a2', value=-2, unit='m', variance=0.01, min=-10, max=0 ) dependent_parameter.make_dependent_on( - dependency_expression="3*a2", dependency_map={"a2": normal_parameter_2} + dependency_expression='3*a2', dependency_map={'a2': normal_parameter_2} ) normal_parameter.value = 3 # Expect self.compare_parameters(dependent_parameter, 3 * normal_parameter_2) - assert dependent_parameter.dependency_expression == "3*a2" - assert dependent_parameter.dependency_map == {"a2": normal_parameter_2} + assert dependent_parameter.dependency_expression == '3*a2' + assert dependent_parameter.dependency_map == {'a2': normal_parameter_2} assert normal_parameter._observers == [] def test_make_independent(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) assert dependent_parameter.independent == False self.compare_parameters(dependent_parameter, 2 * normal_parameter) @@ -752,45 +734,39 @@ def test_independent_setter(self, normal_parameter: Parameter): with pytest.raises(AttributeError): normal_parameter.independent = False - def test_independent_parameter_dependency_expression( - self, normal_parameter: Parameter - ): + def test_independent_parameter_dependency_expression(self, normal_parameter: Parameter): # When Then Expect with pytest.raises(AttributeError): normal_parameter.dependency_expression - def test_dependent_parameter_dependency_expression_setter( - self, normal_parameter: Parameter - ): + def test_dependent_parameter_dependency_expression_setter(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) # Then Expect with pytest.raises(AttributeError): - dependent_parameter.dependency_expression = "3*a" + dependent_parameter.dependency_expression = '3*a' def test_independent_parameter_dependency_map(self, normal_parameter: Parameter): # When Then Expect with pytest.raises(AttributeError): normal_parameter.dependency_map - def test_dependent_parameter_dependency_map_setter( - self, normal_parameter: Parameter - ): + def test_dependent_parameter_dependency_map_setter(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) # Then Expect with pytest.raises(AttributeError): - dependent_parameter.dependency_map = {"a": normal_parameter} + dependent_parameter.dependency_map = {'a': normal_parameter} def test_min(self, parameter: Parameter): # When Then Expect @@ -808,9 +784,9 @@ def test_set_min(self, parameter: Parameter): def test_set_min_dependent_parameter(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) # Then Expect @@ -832,9 +808,9 @@ def test_set_max(self, parameter: Parameter): def test_set_max_dependent_parameter(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) # Then Expect @@ -848,113 +824,107 @@ def test_set_max_exception(self, parameter: Parameter): def test_convert_unit(self, parameter: Parameter): # When Then - parameter.convert_unit("mm") + parameter.convert_unit('mm') # Expect assert parameter._min.value == 0 - assert parameter._min.unit == "mm" + assert parameter._min.unit == 'mm' assert parameter._max.value == 10000 - assert parameter._max.unit == "mm" + assert parameter._max.unit == 'mm' def test_set_desired_unit(self, normal_parameter: Parameter): # When Then dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, - display_name="display_name", + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, + display_name='display_name', ) # Then - dependent_parameter.set_desired_unit("cm") + dependent_parameter.set_desired_unit('cm') # Expect assert dependent_parameter.value == 200 * normal_parameter.value - assert dependent_parameter.unit == "cm" + assert dependent_parameter.unit == 'cm' assert ( dependent_parameter.variance == normal_parameter.variance * 4 * 10000 ) # unit conversion from m to cm squared assert dependent_parameter.min == 200 * normal_parameter.min assert dependent_parameter.max == 200 * normal_parameter.max - assert dependent_parameter._min.unit == "cm" - assert dependent_parameter._max.unit == "cm" + assert dependent_parameter._min.unit == 'cm' + assert dependent_parameter._max.unit == 'cm' # Then normal_parameter.value = 2 # Expect assert dependent_parameter.value == 200 * normal_parameter.value - assert dependent_parameter.unit == "cm" + assert dependent_parameter.unit == 'cm' assert ( dependent_parameter.variance == normal_parameter.variance * 4 * 10000 ) # unit conversion from m to cm squared assert dependent_parameter.min == 200 * normal_parameter.min assert dependent_parameter.max == 200 * normal_parameter.max - assert dependent_parameter._min.unit == "cm" - assert dependent_parameter._max.unit == "cm" + assert dependent_parameter._min.unit == 'cm' + assert dependent_parameter._max.unit == 'cm' - def test_set_desired_unit_incompatible_units_raises( - self, normal_parameter: Parameter - ): + def test_set_desired_unit_incompatible_units_raises(self, normal_parameter: Parameter): # When Then dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, - display_name="display_name", + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, + display_name='display_name', ) # Then Expect with pytest.raises( UnitError, - match="Failed to convert unit from m to s.", + match='Failed to convert unit from m to s.', ): - dependent_parameter.set_desired_unit("s") + dependent_parameter.set_desired_unit('s') def test_set_desired_unit_None(self, normal_parameter: Parameter): # When Then dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, - display_name="display_name", - desired_unit="cm", + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, + display_name='display_name', + desired_unit='cm', ) # EXPECT - assert dependent_parameter.unit == "cm" + assert dependent_parameter.unit == 'cm' # Then dependent_parameter.set_desired_unit(None) # EXPECT assert dependent_parameter.value == 2 * normal_parameter.value - assert dependent_parameter.unit == "m" + assert dependent_parameter.unit == 'm' - def test_set_desired_unit_independent_parameter_raises( - self, normal_parameter: Parameter - ): + def test_set_desired_unit_independent_parameter_raises(self, normal_parameter: Parameter): # When Then Expect with pytest.raises( AttributeError, - match="This is an independent parameter, desired unit can only be set for dependent parameters.", + match='This is an independent parameter, desired unit can only be set for dependent parameters.', ): - normal_parameter.set_desired_unit("cm") + normal_parameter.set_desired_unit('cm') - def test_set_desired_unit_incorrect_unit_type_raises( - self, normal_parameter: Parameter - ): + def test_set_desired_unit_incorrect_unit_type_raises(self, normal_parameter: Parameter): # When Then dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, - display_name="display_name", + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, + display_name='display_name', ) # Then Expect - with pytest.raises(TypeError, match="must be a string"): + with pytest.raises(TypeError, match='must be a string'): dependent_parameter.set_desired_unit(5) def test_set_fixed(self, parameter: Parameter): @@ -967,16 +937,16 @@ def test_set_fixed(self, parameter: Parameter): def test_set_fixed_dependent_parameter(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) # Then Expect with pytest.raises(AttributeError): dependent_parameter.fixed = True - @pytest.mark.parametrize("fixed", ["True", 1]) + @pytest.mark.parametrize('fixed', ['True', 1]) def test_set_fixed_exception(self, parameter: Parameter, fixed): # When Then Expect with pytest.raises(ValueError): @@ -1006,10 +976,7 @@ def test_set_error_exception(self, parameter: Parameter): def test_repr(self, parameter: Parameter): # When Then Expect - assert ( - repr(parameter) - == "" - ) + assert repr(parameter) == "" def test_repr_fixed(self, parameter: Parameter): # When @@ -1017,8 +984,7 @@ def test_repr_fixed(self, parameter: Parameter): # Then Expect assert ( - repr(parameter) - == "" + repr(parameter) == "" ) def test_value_match_callback(self, parameter: Parameter): @@ -1049,14 +1015,14 @@ def test_set_value(self, parameter: Parameter): # Expect parameter._callback.fset.assert_called_with(2) assert parameter._callback.fset.call_count == 1 - assert parameter._scalar == sc.scalar(2, unit="m") + assert parameter._scalar == sc.scalar(2, unit='m') def test_set_value_dependent_parameter(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) # Then Expect @@ -1066,14 +1032,14 @@ def test_set_value_dependent_parameter(self, normal_parameter: Parameter): def test_set_full_value(self, parameter: Parameter): # When Then Expect with pytest.raises(AttributeError): - parameter.full_value = sc.scalar(2, unit="s") + parameter.full_value = sc.scalar(2, unit='s') def test_set_variance_dependent_parameter(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) # Then Expect @@ -1083,9 +1049,9 @@ def test_set_variance_dependent_parameter(self, normal_parameter: Parameter): def test_set_error_dependent_parameter(self, normal_parameter: Parameter): # When dependent_parameter = Parameter.from_dependency( - name="dependent", - dependency_expression="2*a", - dependency_map={"a": normal_parameter}, + name='dependent', + dependency_expression='2*a', + dependency_map={'a': normal_parameter}, ) # Then Expect @@ -1113,25 +1079,25 @@ def test_copy(self, parameter: Parameter): assert parameter_copy._independent == parameter._independent @pytest.mark.parametrize( - "test, expected, expected_reverse", + 'test, expected, expected_reverse', [ ( - Parameter("test", 2, "m", 0.01, -10, 20), - Parameter("name + test", 3, "m", 0.02, -10, 30), - Parameter("test + name", 3, "m", 0.02, -10, 30), + Parameter('test', 2, 'm', 0.01, -10, 20), + Parameter('name + test', 3, 'm', 0.02, -10, 30), + Parameter('test + name', 3, 'm', 0.02, -10, 30), ), ( - Parameter("test", 2, "m", 0.01), - Parameter("name + test", 3, "m", 0.02, min=-np.inf, max=np.inf), - Parameter("test + name", 3, "m", 0.02, min=-np.inf, max=np.inf), + Parameter('test', 2, 'm', 0.01), + Parameter('name + test', 3, 'm', 0.02, min=-np.inf, max=np.inf), + Parameter('test + name', 3, 'm', 0.02, min=-np.inf, max=np.inf), ), ( - Parameter("test", 2, "cm", 0.01, -10, 10), - Parameter("name + test", 1.02, "m", 0.010001, -0.1, 10.1), - Parameter("test + name", 102, "cm", 100.01, -10, 1010), + Parameter('test', 2, 'cm', 0.01, -10, 10), + Parameter('name + test', 1.02, 'm', 0.010001, -0.1, 10.1), + Parameter('test + name', 102, 'cm', 100.01, -10, 1010), ), ], - ids=["regular", "no_bounds", "unit_conversion"], + ids=['regular', 'no_bounds', 'unit_conversion'], ) def test_addition_with_parameter( self, @@ -1162,11 +1128,11 @@ def test_addition_with_parameter( assert result_reverse.min == expected_reverse.min assert result_reverse.max == expected_reverse.max - assert parameter.unit == "m" + assert parameter.unit == 'm' def test_addition_with_scalar(self): # When - parameter = Parameter(name="name", value=1, variance=0.01, min=0, max=10) + parameter = Parameter(name='name', value=1, variance=0.01, min=0, max=10) # Then result = parameter + 1.0 @@ -1175,14 +1141,14 @@ def test_addition_with_scalar(self): # Expect assert result.name == result.unique_name assert result.value == 2.0 - assert result.unit == "dimensionless" + assert result.unit == 'dimensionless' assert result.variance == 0.01 assert result.min == 1.0 assert result.max == 11.0 assert result_reverse.name == result_reverse.unique_name assert result_reverse.value == 2.0 - assert result_reverse.unit == "dimensionless" + assert result_reverse.unit == 'dimensionless' assert result_reverse.variance == 0.01 assert result_reverse.min == 1.0 assert result_reverse.max == 11.0 @@ -1190,9 +1156,7 @@ def test_addition_with_scalar(self): def test_addition_with_descriptor_number(self, parameter: Parameter): # When parameter._callback = property() - descriptor_number = DescriptorNumber( - name="test", value=1, variance=0.1, unit="cm" - ) + descriptor_number = DescriptorNumber(name='test', value=1, variance=0.1, unit='cm') # Then result = parameter + descriptor_number @@ -1202,7 +1166,7 @@ def test_addition_with_descriptor_number(self, parameter: Parameter): assert type(result) == Parameter assert result.name == result.unique_name assert result.value == 1.01 - assert result.unit == "m" + assert result.unit == 'm' assert result.variance == 0.01001 assert result.min == 0.01 assert result.max == 10.01 @@ -1210,25 +1174,25 @@ def test_addition_with_descriptor_number(self, parameter: Parameter): assert type(result_reverse) == Parameter assert result_reverse.name == result_reverse.unique_name assert result_reverse.value == 101.0 - assert result_reverse.unit == "cm" + assert result_reverse.unit == 'cm' assert result_reverse.variance == 100.1 assert result_reverse.min == 1 assert result_reverse.max == 1001 - assert parameter.unit == "m" - assert descriptor_number.unit == "cm" + assert parameter.unit == 'm' + assert descriptor_number.unit == 'cm' @pytest.mark.parametrize( - "test", + 'test', [ 1.0, Parameter( - "test", + 'test', 2, - "s", + 's', ), ], - ids=["add_scalar_to_unit", "incompatible_units"], + ids=['add_scalar_to_unit', 'incompatible_units'], ) def test_addition_exception(self, parameter: Parameter, test): # When Then Expect @@ -1238,25 +1202,25 @@ def test_addition_exception(self, parameter: Parameter, test): result_reverse = test + parameter @pytest.mark.parametrize( - "test, expected, expected_reverse", + 'test, expected, expected_reverse', [ ( - Parameter("test", 2, "m", 0.01, -20, 20), - Parameter("name - test", -1, "m", 0.02, -20, 30), - Parameter("test - name", 1, "m", 0.02, -30, 20), + Parameter('test', 2, 'm', 0.01, -20, 20), + Parameter('name - test', -1, 'm', 0.02, -20, 30), + Parameter('test - name', 1, 'm', 0.02, -30, 20), ), ( - Parameter("test", 2, "m", 0.01), - Parameter("name - test", -1, "m", 0.02, min=-np.inf, max=np.inf), - Parameter("test - name", 1, "m", 0.02, min=-np.inf, max=np.inf), + Parameter('test', 2, 'm', 0.01), + Parameter('name - test', -1, 'm', 0.02, min=-np.inf, max=np.inf), + Parameter('test - name', 1, 'm', 0.02, min=-np.inf, max=np.inf), ), ( - Parameter("test", 2, "cm", 0.01, -10, 10), - Parameter("name - test", 0.98, "m", 0.010001, -0.1, 10.1), - Parameter("test - name", -98, "cm", 100.01, -1010, 10), + Parameter('test', 2, 'cm', 0.01, -10, 10), + Parameter('name - test', 0.98, 'm', 0.010001, -0.1, 10.1), + Parameter('test - name', -98, 'cm', 100.01, -1010, 10), ), ], - ids=["regular", "no_bounds", "unit_conversion"], + ids=['regular', 'no_bounds', 'unit_conversion'], ) def test_subtraction_with_parameter( self, @@ -1287,14 +1251,12 @@ def test_subtraction_with_parameter( assert result_reverse.min == expected_reverse.min assert result_reverse.max == expected_reverse.max - assert parameter.unit == "m" + assert parameter.unit == 'm' def test_subtraction_with_parameter_nan_cases(self): # When - parameter = Parameter( - name="name", value=1, variance=0.01, min=-np.inf, max=np.inf - ) - test = Parameter(name="test", value=2, variance=0.01, min=-np.inf, max=np.inf) + parameter = Parameter(name='name', value=1, variance=0.01, min=-np.inf, max=np.inf) + test = Parameter(name='test', value=2, variance=0.01, min=-np.inf, max=np.inf) # Then result = parameter - test @@ -1303,21 +1265,21 @@ def test_subtraction_with_parameter_nan_cases(self): # Expect assert result.name == result.unique_name assert result.value == -1.0 - assert result.unit == "dimensionless" + assert result.unit == 'dimensionless' assert result.variance == 0.02 assert result.min == -np.inf assert result.max == np.inf assert result_reverse.name == result_reverse.unique_name assert result_reverse.value == 1.0 - assert result_reverse.unit == "dimensionless" + assert result_reverse.unit == 'dimensionless' assert result_reverse.variance == 0.02 assert result_reverse.min == -np.inf assert result_reverse.max == np.inf def test_subtraction_with_scalar(self): # When - parameter = Parameter(name="name", value=2, variance=0.01, min=0, max=10) + parameter = Parameter(name='name', value=2, variance=0.01, min=0, max=10) # Then result = parameter - 1.0 @@ -1326,14 +1288,14 @@ def test_subtraction_with_scalar(self): # Expect assert result.name == result.unique_name assert result.value == 1.0 - assert result.unit == "dimensionless" + assert result.unit == 'dimensionless' assert result.variance == 0.01 assert result.min == -1.0 assert result.max == 9.0 assert result_reverse.name == result_reverse.unique_name assert result_reverse.value == -1.0 - assert result_reverse.unit == "dimensionless" + assert result_reverse.unit == 'dimensionless' assert result_reverse.variance == 0.01 assert result_reverse.min == -9.0 assert result_reverse.max == 1.0 @@ -1341,9 +1303,7 @@ def test_subtraction_with_scalar(self): def test_subtraction_with_descriptor_number(self, parameter: Parameter): # When parameter._callback = property() - descriptor_number = DescriptorNumber( - name="test", value=1, variance=0.1, unit="cm" - ) + descriptor_number = DescriptorNumber(name='test', value=1, variance=0.1, unit='cm') # Then result = parameter - descriptor_number @@ -1353,7 +1313,7 @@ def test_subtraction_with_descriptor_number(self, parameter: Parameter): assert type(result) == Parameter assert result.name == result.unique_name assert result.value == 0.99 - assert result.unit == "m" + assert result.unit == 'm' assert result.variance == 0.01001 assert result.min == -0.01 assert result.max == 9.99 @@ -1361,25 +1321,25 @@ def test_subtraction_with_descriptor_number(self, parameter: Parameter): assert type(result_reverse) == Parameter assert result_reverse.name == result_reverse.unique_name assert result_reverse.value == -99.0 - assert result_reverse.unit == "cm" + assert result_reverse.unit == 'cm' assert result_reverse.variance == 100.1 assert result_reverse.min == -999 assert result_reverse.max == 1 - assert parameter.unit == "m" - assert descriptor_number.unit == "cm" + assert parameter.unit == 'm' + assert descriptor_number.unit == 'cm' @pytest.mark.parametrize( - "test", + 'test', [ 1.0, Parameter( - "test", + 'test', 2, - "s", + 's', ), ], - ids=["sub_scalar_to_unit", "incompatible_units"], + ids=['sub_scalar_to_unit', 'incompatible_units'], ) def test_subtraction_exception(self, parameter: Parameter, test): # When Then Expect @@ -1389,25 +1349,25 @@ def test_subtraction_exception(self, parameter: Parameter, test): result_reverse = test - parameter @pytest.mark.parametrize( - "test, expected, expected_reverse", + 'test, expected, expected_reverse', [ ( - Parameter("test", 2, "m", 0.01, -10, 20), - Parameter("name * test", 2, "m^2", 0.05, -100, 200), - Parameter("test * name", 2, "m^2", 0.05, -100, 200), + Parameter('test', 2, 'm', 0.01, -10, 20), + Parameter('name * test', 2, 'm^2', 0.05, -100, 200), + Parameter('test * name', 2, 'm^2', 0.05, -100, 200), ), ( - Parameter("test", 2, "m", 0.01), - Parameter("name * test", 2, "m^2", 0.05, min=-np.inf, max=np.inf), - Parameter("test * name", 2, "m^2", 0.05, min=-np.inf, max=np.inf), + Parameter('test', 2, 'm', 0.01), + Parameter('name * test', 2, 'm^2', 0.05, min=-np.inf, max=np.inf), + Parameter('test * name', 2, 'm^2', 0.05, min=-np.inf, max=np.inf), ), ( - Parameter("test", 2, "dm", 0.01, -10, 20), - Parameter("name * test", 0.2, "m^2", 0.0005, -10, 20), - Parameter("test * name", 0.2, "m^2", 0.0005, -10, 20), + Parameter('test', 2, 'dm', 0.01, -10, 20), + Parameter('name * test', 0.2, 'm^2', 0.0005, -10, 20), + Parameter('test * name', 0.2, 'm^2', 0.0005, -10, 20), ), ], - ids=["regular", "no_bounds", "base_unit_conversion"], + ids=['regular', 'no_bounds', 'base_unit_conversion'], ) def test_multiplication_with_parameter( self, @@ -1439,26 +1399,24 @@ def test_multiplication_with_parameter( assert result_reverse.max == expected_reverse.max @pytest.mark.parametrize( - "test, expected, expected_reverse", + 'test, expected, expected_reverse', [ ( - Parameter("test", 0, "", 0.01, -10, 0), - Parameter("name * test", 0.0, "dimensionless", 0.01, -np.inf, 0), - Parameter("test * name", 0, "dimensionless", 0.01, -np.inf, 0), + Parameter('test', 0, '', 0.01, -10, 0), + Parameter('name * test', 0.0, 'dimensionless', 0.01, -np.inf, 0), + Parameter('test * name', 0, 'dimensionless', 0.01, -np.inf, 0), ), ( - Parameter("test", 0, "", 0.01, 0, 10), - Parameter("name * test", 0.0, "dimensionless", 0.01, 0, np.inf), - Parameter("test * name", 0, "dimensionless", 0.01, 0, np.inf), + Parameter('test', 0, '', 0.01, 0, 10), + Parameter('name * test', 0.0, 'dimensionless', 0.01, 0, np.inf), + Parameter('test * name', 0, 'dimensionless', 0.01, 0, np.inf), ), ], - ids=["zero_min", "zero_max"], + ids=['zero_min', 'zero_max'], ) - def test_multiplication_with_parameter_nan_cases( - self, test, expected, expected_reverse - ): + def test_multiplication_with_parameter_nan_cases(self, test, expected, expected_reverse): # When - parameter = Parameter(name="name", value=1, variance=0.01, min=1, max=np.inf) + parameter = Parameter(name='name', value=1, variance=0.01, min=1, max=np.inf) # Then result = parameter * test @@ -1480,20 +1438,20 @@ def test_multiplication_with_parameter_nan_cases( assert result_reverse.max == expected_reverse.max @pytest.mark.parametrize( - "test, expected, expected_reverse", + 'test, expected, expected_reverse', [ ( - DescriptorNumber(name="test", value=2, variance=0.1, unit="cm"), - Parameter("name * test", 2, "dm^2", 0.14, 0, 20), - Parameter("test * name", 2, "dm^2", 0.14, 0, 20), + DescriptorNumber(name='test', value=2, variance=0.1, unit='cm'), + Parameter('name * test', 2, 'dm^2', 0.14, 0, 20), + Parameter('test * name', 2, 'dm^2', 0.14, 0, 20), ), ( - DescriptorNumber(name="test", value=0, variance=0.1, unit="cm"), - DescriptorNumber("name * test", 0, "dm^2", 0.1), - DescriptorNumber("test * name", 0, "dm^2", 0.1), + DescriptorNumber(name='test', value=0, variance=0.1, unit='cm'), + DescriptorNumber('name * test', 0, 'dm^2', 0.1), + DescriptorNumber('test * name', 0, 'dm^2', 0.1), ), ], - ids=["regular", "zero_value"], + ids=['regular', 'zero_value'], ) def test_multiplication_with_descriptor_number( self, parameter: Parameter, test, expected, expected_reverse @@ -1525,20 +1483,20 @@ def test_multiplication_with_descriptor_number( assert result_reverse.max == expected_reverse.max @pytest.mark.parametrize( - "test, expected, expected_reverse", + 'test, expected, expected_reverse', [ ( 2, - Parameter("name * 2", 2, "m", 0.04, 0, 20), - Parameter("2 * name", 2, "m", 0.04, 0, 20), + Parameter('name * 2', 2, 'm', 0.04, 0, 20), + Parameter('2 * name', 2, 'm', 0.04, 0, 20), ), ( 0, - DescriptorNumber("name * 0", 0, "m", 0), - DescriptorNumber("0 * name", 0, "m", 0), + DescriptorNumber('name * 0', 0, 'm', 0), + DescriptorNumber('0 * name', 0, 'm', 0), ), ], - ids=["regular", "zero_value"], + ids=['regular', 'zero_value'], ) def test_multiplication_with_scalar( self, parameter: Parameter, test, expected, expected_reverse @@ -1569,29 +1527,27 @@ def test_multiplication_with_scalar( assert result_reverse.max == expected_reverse.max @pytest.mark.parametrize( - "test, expected, expected_reverse", + 'test, expected, expected_reverse', [ ( - Parameter("test", 2, "s", 0.01, -10, 20), - Parameter("name / test", 0.5, "m/s", 0.003125, -np.inf, np.inf), - Parameter("test / name", 2, "s/m", 0.05, -np.inf, np.inf), + Parameter('test', 2, 's', 0.01, -10, 20), + Parameter('name / test', 0.5, 'm/s', 0.003125, -np.inf, np.inf), + Parameter('test / name', 2, 's/m', 0.05, -np.inf, np.inf), ), ( - Parameter("test", 2, "s", 0.01, 0, 20), - Parameter("name / test", 0.5, "m/s", 0.003125, 0.0, np.inf), - Parameter("test / name", 2, "s/m", 0.05, 0.0, np.inf), + Parameter('test', 2, 's', 0.01, 0, 20), + Parameter('name / test', 0.5, 'm/s', 0.003125, 0.0, np.inf), + Parameter('test / name', 2, 's/m', 0.05, 0.0, np.inf), ), ( - Parameter("test", -2, "s", 0.01, -10, 0), - Parameter("name / test", -0.5, "m/s", 0.003125, -np.inf, 0.0), - Parameter("test / name", -2, "s/m", 0.05, -np.inf, 0.0), + Parameter('test', -2, 's', 0.01, -10, 0), + Parameter('name / test', -0.5, 'm/s', 0.003125, -np.inf, 0.0), + Parameter('test / name', -2, 's/m', 0.05, -np.inf, 0.0), ), ], - ids=["crossing_zero", "only_positive", "only_negative"], + ids=['crossing_zero', 'only_positive', 'only_negative'], ) - def test_division_with_parameter( - self, parameter: Parameter, test, expected, expected_reverse - ): + def test_division_with_parameter(self, parameter: Parameter, test, expected, expected_reverse): # When parameter._callback = property() @@ -1617,28 +1573,28 @@ def test_division_with_parameter( assert result_reverse.max == expected_reverse.max @pytest.mark.parametrize( - "first, second, expected", + 'first, second, expected', [ ( - Parameter("name", 1, "m", 0.01, -10, 20), - Parameter("test", -2, "s", 0.01, -10, 0), - Parameter("name / test", -0.5, "m/s", 0.003125, -np.inf, np.inf), + Parameter('name', 1, 'm', 0.01, -10, 20), + Parameter('test', -2, 's', 0.01, -10, 0), + Parameter('name / test', -0.5, 'm/s', 0.003125, -np.inf, np.inf), ), ( - Parameter("name", -10, "m", 0.01, -20, -10), - Parameter("test", -2, "s", 0.01, -10, 0), - Parameter("name / test", 5.0, "m/s", 0.065, 1, np.inf), + Parameter('name', -10, 'm', 0.01, -20, -10), + Parameter('test', -2, 's', 0.01, -10, 0), + Parameter('name / test', 5.0, 'm/s', 0.065, 1, np.inf), ), ( - Parameter("name", 10, "m", 0.01, 10, 20), - Parameter("test", -20, "s", 0.01, -20, -10), - Parameter("name / test", -0.5, "m/s", 3.125e-5, -2, -0.5), + Parameter('name', 10, 'm', 0.01, 10, 20), + Parameter('test', -20, 's', 0.01, -20, -10), + Parameter('name / test', -0.5, 'm/s', 3.125e-5, -2, -0.5), ), ], ids=[ - "first_crossing_zero_second_negative_0", - "both_negative_second_negative_0", - "finite_limits", + 'first_crossing_zero_second_negative_0', + 'both_negative_second_negative_0', + 'finite_limits', ], ) def test_division_with_parameter_remaining_cases(self, first, second, expected): @@ -1654,20 +1610,20 @@ def test_division_with_parameter_remaining_cases(self, first, second, expected): assert result.max == expected.max @pytest.mark.parametrize( - "test, expected, expected_reverse", + 'test, expected, expected_reverse', [ ( - DescriptorNumber(name="test", value=2, variance=0.1, unit="s"), - Parameter("name / test", 0.5, "m/s", 0.00875, 0, 5), - Parameter("test / name", 2, "s/m", 0.14, 0.2, np.inf), + DescriptorNumber(name='test', value=2, variance=0.1, unit='s'), + Parameter('name / test', 0.5, 'm/s', 0.00875, 0, 5), + Parameter('test / name', 2, 's/m', 0.14, 0.2, np.inf), ), ( 2, - Parameter("name / 2", 0.5, "m", 0.0025, 0, 5), - Parameter("2 / name", 2, "m**-1", 0.04, 0.2, np.inf), + Parameter('name / 2', 0.5, 'm', 0.0025, 0, 5), + Parameter('2 / name', 2, 'm**-1', 0.04, 0.2, np.inf), ), ], - ids=["descriptor_number", "number"], + ids=['descriptor_number', 'number'], ) def test_division_with_descriptor_number_and_number( self, parameter: Parameter, test, expected, expected_reverse @@ -1697,19 +1653,17 @@ def test_division_with_descriptor_number_and_number( assert result_reverse.max == expected_reverse.max @pytest.mark.parametrize( - "test, expected", + 'test, expected', [ ( - DescriptorNumber(name="test", value=0, variance=0.1, unit="s"), - DescriptorNumber("test / name", 0.0, "s/m", 0.1), + DescriptorNumber(name='test', value=0, variance=0.1, unit='s'), + DescriptorNumber('test / name', 0.0, 's/m', 0.1), ), - (0, DescriptorNumber("0 / name", 0.0, "1/m", 0.0)), + (0, DescriptorNumber('0 / name', 0.0, '1/m', 0.0)), ], - ids=["descriptor_number", "number"], + ids=['descriptor_number', 'number'], ) - def test_zero_value_divided_by_parameter( - self, parameter: Parameter, test, expected - ): + def test_zero_value_divided_by_parameter(self, parameter: Parameter, test, expected): # When parameter._callback = property() @@ -1724,45 +1678,43 @@ def test_zero_value_divided_by_parameter( assert result.variance == expected.variance @pytest.mark.parametrize( - "first, second, expected", + 'first, second, expected', [ ( - DescriptorNumber("name", 1, "m", 0.01), - Parameter("test", 2, "s", 0.1, -10, 10), - Parameter("name / test", 0.5, "m/s", 0.00875, -np.inf, np.inf), + DescriptorNumber('name', 1, 'm', 0.01), + Parameter('test', 2, 's', 0.1, -10, 10), + Parameter('name / test', 0.5, 'm/s', 0.00875, -np.inf, np.inf), ), ( - DescriptorNumber("name", -1, "m", 0.01), - Parameter("test", 2, "s", 0.1, 0, 10), - Parameter("name / test", -0.5, "m/s", 0.00875, -np.inf, -0.1), + DescriptorNumber('name', -1, 'm', 0.01), + Parameter('test', 2, 's', 0.1, 0, 10), + Parameter('name / test', -0.5, 'm/s', 0.00875, -np.inf, -0.1), ), ( - DescriptorNumber("name", 1, "m", 0.01), - Parameter("test", -2, "s", 0.1, -10, 0), - Parameter("name / test", -0.5, "m/s", 0.00875, -np.inf, -0.1), + DescriptorNumber('name', 1, 'm', 0.01), + Parameter('test', -2, 's', 0.1, -10, 0), + Parameter('name / test', -0.5, 'm/s', 0.00875, -np.inf, -0.1), ), ( - DescriptorNumber("name", -1, "m", 0.01), - Parameter("test", -2, "s", 0.1, -10, 0), - Parameter("name / test", 0.5, "m/s", 0.00875, 0.1, np.inf), + DescriptorNumber('name', -1, 'm', 0.01), + Parameter('test', -2, 's', 0.1, -10, 0), + Parameter('name / test', 0.5, 'm/s', 0.00875, 0.1, np.inf), ), ( - DescriptorNumber("name", 1, "m", 0.01), - Parameter("test", 2, "s", 0.1, 1, 10), - Parameter("name / test", 0.5, "m/s", 0.00875, 0.1, 1), + DescriptorNumber('name', 1, 'm', 0.01), + Parameter('test', 2, 's', 0.1, 1, 10), + Parameter('name / test', 0.5, 'm/s', 0.00875, 0.1, 1), ), ], ids=[ - "crossing_zero", - "positive_0_with_negative", - "negative_0_with_positive", - "negative_0_with_negative", - "finite_limits", + 'crossing_zero', + 'positive_0_with_negative', + 'negative_0_with_positive', + 'negative_0_with_negative', + 'finite_limits', ], ) - def test_division_with_descriptor_number_missing_cases( - self, first, second, expected - ): + def test_division_with_descriptor_number_missing_cases(self, first, second, expected): # When Then result = first / second @@ -1775,9 +1727,9 @@ def test_division_with_descriptor_number_missing_cases( assert result.max == expected.max @pytest.mark.parametrize( - "test", - [0, DescriptorNumber("test", 0, "s", 0.1)], - ids=["number", "descriptor_number"], + 'test', + [0, DescriptorNumber('test', 0, 's', 0.1)], + ids=['number', 'descriptor_number'], ) def test_divide_parameter_by_zero(self, parameter: Parameter, test): # When @@ -1789,38 +1741,38 @@ def test_divide_parameter_by_zero(self, parameter: Parameter, test): def test_divide_by_zero_value_parameter(self): # When - descriptor = DescriptorNumber("test", 1, "s", 0.1) - parameter = Parameter("name", 0, "m", 0.01) + descriptor = DescriptorNumber('test', 1, 's', 0.1) + parameter = Parameter('name', 0, 'm', 0.01) # Then Expect with pytest.raises(ZeroDivisionError): result = descriptor / parameter @pytest.mark.parametrize( - "test, expected", + 'test, expected', [ - (3, Parameter("name ** 3", 125, "m^3", 281.25, -125, 1000)), - (2, Parameter("name ** 2", 25, "m^2", 5.0, 0, 100)), - (-1, Parameter("name ** -1", 0.2, "1/m", 8e-5, -np.inf, np.inf)), - (-2, Parameter("name ** -2", 0.04, "1/m^2", 1.28e-5, 0, np.inf)), - (0, DescriptorNumber("name ** 0", 1, "dimensionless", 0)), + (3, Parameter('name ** 3', 125, 'm^3', 281.25, -125, 1000)), + (2, Parameter('name ** 2', 25, 'm^2', 5.0, 0, 100)), + (-1, Parameter('name ** -1', 0.2, '1/m', 8e-5, -np.inf, np.inf)), + (-2, Parameter('name ** -2', 0.04, '1/m^2', 1.28e-5, 0, np.inf)), + (0, DescriptorNumber('name ** 0', 1, 'dimensionless', 0)), ( - DescriptorNumber("test", 2), - Parameter("name ** test", 25, "m^2", 5.0, 0, 100), + DescriptorNumber('test', 2), + Parameter('name ** test', 25, 'm^2', 5.0, 0, 100), ), ], ids=[ - "power_3", - "power_2", - "power_-1", - "power_-2", - "power_0", - "power_descriptor_number", + 'power_3', + 'power_2', + 'power_-1', + 'power_-2', + 'power_0', + 'power_descriptor_number', ], ) def test_power_of_parameter(self, test, expected): # When - parameter = Parameter("name", 5, "m", 0.05, -5, 10) + parameter = Parameter('name', 5, 'm', 0.05, -5, 10) # Then result = parameter**test @@ -1836,59 +1788,59 @@ def test_power_of_parameter(self, test, expected): assert result.max == expected.max @pytest.mark.parametrize( - "test, exponent, expected", + 'test, exponent, expected', [ ( - Parameter("name", 5, "m", 0.05, 0, 10), + Parameter('name', 5, 'm', 0.05, 0, 10), -1, - Parameter("name ** -1", 0.2, "1/m", 8e-5, 0.1, np.inf), + Parameter('name ** -1', 0.2, '1/m', 8e-5, 0.1, np.inf), ), ( - Parameter("name", -5, "m", 0.05, -5, 0), + Parameter('name', -5, 'm', 0.05, -5, 0), -1, - Parameter("name ** -1", -0.2, "1/m", 8e-5, -np.inf, -0.2), + Parameter('name ** -1', -0.2, '1/m', 8e-5, -np.inf, -0.2), ), ( - Parameter("name", 5, "m", 0.05, 5, 10), + Parameter('name', 5, 'm', 0.05, 5, 10), -1, - Parameter("name ** -1", 0.2, "1/m", 8e-5, 0.1, 0.2), + Parameter('name ** -1', 0.2, '1/m', 8e-5, 0.1, 0.2), ), ( - Parameter("name", -5, "m", 0.05, -10, -5), + Parameter('name', -5, 'm', 0.05, -10, -5), -1, - Parameter("name ** -1", -0.2, "1/m", 8e-5, -0.2, -0.1), + Parameter('name ** -1', -0.2, '1/m', 8e-5, -0.2, -0.1), ), ( - Parameter("name", -5, "m", 0.05, -10, -5), + Parameter('name', -5, 'm', 0.05, -10, -5), -2, - Parameter("name ** -2", 0.04, "1/m^2", 1.28e-5, 0.01, 0.04), + Parameter('name ** -2', 0.04, '1/m^2', 1.28e-5, 0.01, 0.04), ), ( - Parameter("name", 5, "", 0.1, 1, 10), + Parameter('name', 5, '', 0.1, 1, 10), 0.3, Parameter( - "name ** 0.3", + 'name ** 0.3', 1.6206565966927624, - "", + '', 0.0009455500095853564, 1, 1.9952623149688795, ), ), ( - Parameter("name", 5, "", 0.1), + Parameter('name', 5, '', 0.1), 0.5, - Parameter("name ** 0.5", 2.23606797749979, "", 0.005, 0, np.inf), + Parameter('name ** 0.5', 2.23606797749979, '', 0.005, 0, np.inf), ), ], ids=[ - "0_positive", - "negative_0", - "both_positive", - "both_negative_invert", - "both_negative_invert_square", - "fractional", - "fractional_negative_limit", + '0_positive', + 'negative_0', + 'both_positive', + 'both_negative_invert', + 'both_negative_invert_square', + 'fractional', + 'fractional_negative_limit', ], ) def test_power_of_diffent_parameters(self, test, exponent, expected): @@ -1904,26 +1856,26 @@ def test_power_of_diffent_parameters(self, test, exponent, expected): assert result.max == expected.max @pytest.mark.parametrize( - "parameter, exponent, expected", + 'parameter, exponent, expected', [ ( - Parameter("name", 5, "m"), - DescriptorNumber("test", 2, unit="s"), + Parameter('name', 5, 'm'), + DescriptorNumber('test', 2, unit='s'), UnitError, ), ( - Parameter("name", 5, "m"), - DescriptorNumber("test", 2, variance=0.01), + Parameter('name', 5, 'm'), + DescriptorNumber('test', 2, variance=0.01), ValueError, ), - (Parameter("name", 5, "m"), 0.5, UnitError), - (Parameter("name", -5, ""), 0.5, ValueError), + (Parameter('name', 5, 'm'), 0.5, UnitError), + (Parameter('name', -5, ''), 0.5, ValueError), ], ids=[ - "exponent_unit", - "exponent_variance", - "exponent_fractional", - "negative_base_fractional", + 'exponent_unit', + 'exponent_variance', + 'exponent_fractional', + 'negative_base_fractional', ], ) def test_power_exceptions(self, parameter, exponent, expected): @@ -1933,7 +1885,7 @@ def test_power_exceptions(self, parameter, exponent, expected): def test_negation(self): # When - parameter = Parameter("name", 5, "m", 0.05, -5, 10) + parameter = Parameter('name', 5, 'm', 0.05, -5, 10) # Then result = -parameter @@ -1941,24 +1893,24 @@ def test_negation(self): # Expect assert result.name == result.unique_name assert result.value == -5 - assert result.unit == "m" + assert result.unit == 'm' assert result.variance == 0.05 assert result.min == -10 assert result.max == 5 @pytest.mark.parametrize( - "test, expected", + 'test, expected', [ ( - Parameter("name", -5, "m", 0.05, -10, -5), - Parameter("abs(name)", 5, "m", 0.05, 5, 10), + Parameter('name', -5, 'm', 0.05, -10, -5), + Parameter('abs(name)', 5, 'm', 0.05, 5, 10), ), ( - Parameter("name", 5, "m", 0.05, -10, 10), - Parameter("abs(name)", 5, "m", 0.05, 0, 10), + Parameter('name', 5, 'm', 0.05, -10, 10), + Parameter('abs(name)', 5, 'm', 0.05, 0, 10), ), ], - ids=["pure_negative", "crossing_zero"], + ids=['pure_negative', 'crossing_zero'], ) def test_abs(self, test, expected): # When Then diff --git a/tests/unit_tests/variable/test_parameter_dependency_serialization.py b/tests/unit/variable/test_parameter_dependency_serialization.py similarity index 61% rename from tests/unit_tests/variable/test_parameter_dependency_serialization.py rename to tests/unit/variable/test_parameter_dependency_serialization.py index 574e2497..62feb5f3 100644 --- a/tests/unit_tests/variable/test_parameter_dependency_serialization.py +++ b/tests/unit/variable/test_parameter_dependency_serialization.py @@ -1,22 +1,20 @@ -import pytest +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + import json -from copy import deepcopy -from unittest.mock import Mock -from easyscience import Parameter, global_object -from easyscience.variable.parameter_dependency_resolver import ( - resolve_all_parameter_dependencies, -) +import pytest + +from easyscience import Parameter +from easyscience import global_object +from easyscience.variable.parameter_dependency_resolver import deserialize_and_resolve_parameters from easyscience.variable.parameter_dependency_resolver import ( get_parameters_with_pending_dependencies, ) -from easyscience.variable.parameter_dependency_resolver import ( - deserialize_and_resolve_parameters, -) +from easyscience.variable.parameter_dependency_resolver import resolve_all_parameter_dependencies class TestParameterDependencySerialization: - @pytest.fixture def clear_global_map(self): """This fixture pattern: @@ -39,15 +37,15 @@ def clear_global_map(self): def test_independent_parameter_serialization(self, clear_global_map): """Test that independent parameters serialize normally without dependency info.""" - param = Parameter(name="test", value=5.0, unit="m", min=0, max=10) + param = Parameter(name='test', value=5.0, unit='m', min=0, max=10) # Serialize serialized = param.as_dict() # Should not contain dependency fields - assert "_dependency_string" not in serialized - assert "_dependency_map_serializer_ids" not in serialized - assert "_independent" not in serialized + assert '_dependency_string' not in serialized + assert '_dependency_map_serializer_ids' not in serialized + assert '_independent' not in serialized # Deserialize global_object.map._clear() @@ -62,55 +60,53 @@ def test_independent_parameter_serialization(self, clear_global_map): def test_dependent_parameter_serialization(self, clear_global_map): """Test serialization of parameters with dependencies.""" # Create independent parameter - a = Parameter(name="a", value=2.0, unit="m", min=0, max=10) + a = Parameter(name='a', value=2.0, unit='m', min=0, max=10) # Create dependent parameter b = Parameter.from_dependency( - name="b", dependency_expression="2 * a", dependency_map={"a": a}, unit="m" + name='b', dependency_expression='2 * a', dependency_map={'a': a}, unit='m' ) # Serialize dependent parameter serialized = b.as_dict() # Should contain dependency information - assert serialized["_dependency_string"] == "2 * a" - assert serialized["_dependency_map_serializer_ids"] == { - "a": a._DescriptorNumber__serializer_id + assert serialized['_dependency_string'] == '2 * a' + assert serialized['_dependency_map_serializer_ids'] == { + 'a': a._DescriptorNumber__serializer_id } - assert serialized["_independent"] is False + assert serialized['_independent'] is False # Deserialize global_object.map._clear() new_b = Parameter.from_dict(serialized) # Should have pending dependency info - assert hasattr(new_b, "_pending_dependency_string") - assert new_b._pending_dependency_string == "2 * a" + assert hasattr(new_b, '_pending_dependency_string') + assert new_b._pending_dependency_string == '2 * a' assert new_b._pending_dependency_map_serializer_ids == { - "a": a._DescriptorNumber__serializer_id + 'a': a._DescriptorNumber__serializer_id } - assert ( - new_b.independent is True - ) # Initially independent until dependencies resolved + assert new_b.independent is True # Initially independent until dependencies resolved def test_dependency_resolution_after_deserialization(self, clear_global_map): """Test that dependencies are properly resolved after deserialization.""" # Create test parameters with dependencies - a = Parameter(name="a", value=2.0, unit="m", min=0, max=10) - b = Parameter(name="b", value=3.0, unit="m", min=0, max=10) + a = Parameter(name='a', value=2.0, unit='m', min=0, max=10) + b = Parameter(name='b', value=3.0, unit='m', min=0, max=10) c = Parameter.from_dependency( - name="c", - dependency_expression="a + b", - dependency_map={"a": a, "b": b}, - unit="m", + name='c', + dependency_expression='a + b', + dependency_map={'a': a, 'b': b}, + unit='m', ) # Verify original dependency works assert c.value == 5.0 # 2 + 3 # Serialize all parameters - params_data = {"a": a.as_dict(), "b": b.as_dict(), "c": c.as_dict()} + params_data = {'a': a.as_dict(), 'b': b.as_dict(), 'c': c.as_dict()} # Clear and deserialize (manual approach) global_object.map._clear() @@ -119,8 +115,8 @@ def test_dependency_resolution_after_deserialization(self, clear_global_map): new_params[name] = Parameter.from_dict(data) # Before resolution, c should be independent with pending dependency - assert new_params["c"].independent is True - assert hasattr(new_params["c"], "_pending_dependency_string") + assert new_params['c'].independent is True + assert hasattr(new_params['c'], '_pending_dependency_string') # Resolve dependencies resolve_all_parameter_dependencies(new_params) @@ -130,34 +126,32 @@ def test_dependency_resolution_after_deserialization(self, clear_global_map): # new_params = deserialize_and_resolve_parameters(params_data) # After resolution, c should be dependent and functional - assert new_params["c"].independent is False - assert new_params["c"].value == 5.0 # Still 2 + 3 + assert new_params['c'].independent is False + assert new_params['c'].value == 5.0 # Still 2 + 3 # Test that dependency still works - new_params["a"].value = 10.0 - assert new_params["c"].value == 13.0 # 10 + 3 + new_params['a'].value = 10.0 + assert new_params['c'].value == 13.0 # 10 + 3 - def test_dependency_resolution_after_deserialization_desired_unit( - self, clear_global_map - ): + def test_dependency_resolution_after_deserialization_desired_unit(self, clear_global_map): """Test that dependencies are properly resolved after deserialization.""" # Create test parameters with dependencies - a = Parameter(name="a", value=2.0, unit="m", min=0, max=10) - b = Parameter(name="b", value=3.0, unit="m", min=0, max=10) + a = Parameter(name='a', value=2.0, unit='m', min=0, max=10) + b = Parameter(name='b', value=3.0, unit='m', min=0, max=10) c = Parameter.from_dependency( - name="c", - dependency_expression="a + b", - dependency_map={"a": a, "b": b}, - desired_unit="cm", + name='c', + dependency_expression='a + b', + dependency_map={'a': a, 'b': b}, + desired_unit='cm', ) # Verify original dependency works assert c.value == 5.0 * 100 # 2 + 3 - assert c.unit == "cm" + assert c.unit == 'cm' # Serialize all parameters - params_data = {"a": a.as_dict(), "b": b.as_dict(), "c": c.as_dict()} + params_data = {'a': a.as_dict(), 'b': b.as_dict(), 'c': c.as_dict()} # Clear and deserialize (manual approach) global_object.map._clear() @@ -166,8 +160,8 @@ def test_dependency_resolution_after_deserialization_desired_unit( new_params[name] = Parameter.from_dict(data) # Before resolution, c should be independent with pending dependency - assert new_params["c"].independent is True - assert hasattr(new_params["c"], "_pending_dependency_string") + assert new_params['c'].independent is True + assert hasattr(new_params['c'], '_pending_dependency_string') # Resolve dependencies resolve_all_parameter_dependencies(new_params) @@ -177,24 +171,24 @@ def test_dependency_resolution_after_deserialization_desired_unit( # new_params = deserialize_and_resolve_parameters(params_data) # After resolution, c should be dependent and functional - assert new_params["c"].independent is False - assert new_params["c"]._desired_unit == "cm" # Desired unit should be preserved - assert new_params["c"].value == 5.0 * 100 # Still 2 + 3, converted to cm + assert new_params['c'].independent is False + assert new_params['c']._desired_unit == 'cm' # Desired unit should be preserved + assert new_params['c'].value == 5.0 * 100 # Still 2 + 3, converted to cm # Test that dependency still works - new_params["a"].value = 10.0 - assert new_params["c"].value == 13.0 * 100 # 10 + 3 - assert new_params["c"].unit == "cm" + new_params['a'].value = 10.0 + assert new_params['c'].value == 13.0 * 100 # 10 + 3 + assert new_params['c'].unit == 'cm' def test_unique_name_dependency_serialization(self, clear_global_map): """Test serialization of dependencies using unique names.""" - a = Parameter(name="a", value=3.0, unit="m", min=0, max=10) + a = Parameter(name='a', value=3.0, unit='m', min=0, max=10) # Create dependent parameter using unique name b = Parameter.from_dependency( - name="b", + name='b', dependency_expression='2 * "Parameter_0"', # Using unique name - unit="m", + unit='m', ) # Serialize both parameters @@ -202,26 +196,26 @@ def test_unique_name_dependency_serialization(self, clear_global_map): b_serialized = b.as_dict() # Should contain unique name mapping - assert b_serialized["_dependency_string"] == "2 * __Parameter_0__" - assert "__Parameter_0__" in b_serialized["_dependency_map_serializer_ids"] + assert b_serialized['_dependency_string'] == '2 * __Parameter_0__' + assert '__Parameter_0__' in b_serialized['_dependency_map_serializer_ids'] assert ( - b_serialized["_dependency_map_serializer_ids"]["__Parameter_0__"] + b_serialized['_dependency_map_serializer_ids']['__Parameter_0__'] == a._DescriptorNumber__serializer_id ) # Deserialize both and resolve global_object.map._clear() c = Parameter( - name="c", value=0.0 + name='c', value=0.0 ) # Dummy to occupy unique name, to force new unique_names # Remove unique_name from serialized data to force generation of new unique names - a_serialized.pop("unique_name", None) - b_serialized.pop("unique_name", None) + a_serialized.pop('unique_name', None) + b_serialized.pop('unique_name', None) new_b = Parameter.from_dict(b_serialized) new_a = Parameter.from_dict(a_serialized) - resolve_all_parameter_dependencies({"a": new_a, "b": new_b}) + resolve_all_parameter_dependencies({'a': new_a, 'b': new_b}) # Should work correctly assert new_b.independent is False @@ -231,21 +225,21 @@ def test_unique_name_dependency_serialization(self, clear_global_map): def test_json_serialization_roundtrip(self, clear_global_map): """Test that parameter dependencies survive JSON serialization.""" # Create parameters with dependencies - length = Parameter(name="length", value=10.0, unit="m", min=0, max=100) - width = Parameter(name="width", value=5.0, unit="m", min=0, max=50) + length = Parameter(name='length', value=10.0, unit='m', min=0, max=100) + width = Parameter(name='width', value=5.0, unit='m', min=0, max=50) area = Parameter.from_dependency( - name="area", - dependency_expression="length * width", - dependency_map={"length": length, "width": width}, - unit="m^2", + name='area', + dependency_expression='length * width', + dependency_map={'length': length, 'width': width}, + unit='m^2', ) # Serialize to JSON params_data = { - "length": length.as_dict(), - "width": width.as_dict(), - "area": area.as_dict(), + 'length': length.as_dict(), + 'width': width.as_dict(), + 'area': area.as_dict(), } json_str = json.dumps(params_data, default=str) @@ -260,26 +254,26 @@ def test_json_serialization_roundtrip(self, clear_global_map): resolve_all_parameter_dependencies(new_params) # Test functionality - assert new_params["area"].value == 50.0 # 10 * 5 + assert new_params['area'].value == 50.0 # 10 * 5 # Test dependency updates - new_params["length"].value = 20.0 - assert new_params["area"].value == 100.0 # 20 * 5 + new_params['length'].value = 20.0 + assert new_params['area'].value == 100.0 # 20 * 5 def test_multiple_dependent_parameters(self, clear_global_map): """Test serialization with multiple dependent parameters.""" # Create a chain of dependencies - x = Parameter(name="x", value=2.0, unit="m", min=0, max=10) + x = Parameter(name='x', value=2.0, unit='m', min=0, max=10) y = Parameter.from_dependency( - name="y", dependency_expression="2 * x", dependency_map={"x": x}, unit="m" + name='y', dependency_expression='2 * x', dependency_map={'x': x}, unit='m' ) z = Parameter.from_dependency( - name="z", - dependency_expression="y + x", - dependency_map={"y": y, "x": x}, - unit="m", + name='z', + dependency_expression='y + x', + dependency_map={'y': y, 'x': x}, + unit='m', ) # Verify original chain works @@ -287,7 +281,7 @@ def test_multiple_dependent_parameters(self, clear_global_map): assert z.value == 6.0 # 4 + 2 # Serialize all - params_data = {"x": x.as_dict(), "y": y.as_dict(), "z": z.as_dict()} + params_data = {'x': x.as_dict(), 'y': y.as_dict(), 'z': z.as_dict()} # Deserialize and resolve global_object.map._clear() @@ -298,13 +292,13 @@ def test_multiple_dependent_parameters(self, clear_global_map): resolve_all_parameter_dependencies(new_params) # Test chain still works - assert new_params["y"].value == 4.0 - assert new_params["z"].value == 6.0 + assert new_params['y'].value == 4.0 + assert new_params['z'].value == 6.0 # Test cascade updates - new_params["x"].value = 5.0 - assert new_params["y"].value == 10.0 # 2 * 5 - assert new_params["z"].value == 15.0 # 10 + 5 + new_params['x'].value = 5.0 + assert new_params['y'].value == 10.0 # 2 * 5 + assert new_params['z'].value == 15.0 # 10 + 5 def test_dependency_with_descriptor_number(self, clear_global_map): """Test that dependencies involving DescriptorNumber serialize correctly.""" @@ -312,12 +306,12 @@ def test_dependency_with_descriptor_number(self, clear_global_map): # When - x = DescriptorNumber(name="x", value=3.0, unit="m") - y = Parameter(name="y", value=4.0, unit="m") + x = DescriptorNumber(name='x', value=3.0, unit='m') + y = Parameter(name='y', value=4.0, unit='m') z = Parameter.from_dependency( - name="z", - dependency_expression="x + y", - dependency_map={"x": x, "y": y}, + name='z', + dependency_expression='x + y', + dependency_map={'x': x, 'y': y}, ) # Verify original functionality @@ -325,12 +319,12 @@ def test_dependency_with_descriptor_number(self, clear_global_map): # Then # Serialize all - params_data = {"x": x.as_dict(), "y": y.as_dict(), "z": z.as_dict()} + params_data = {'x': x.as_dict(), 'y': y.as_dict(), 'z': z.as_dict()} # Deserialize and resolve global_object.map._clear() new_params = {} for name, data in params_data.items(): - if name == "x": + if name == 'x': new_params[name] = DescriptorNumber.from_dict(data) else: new_params[name] = Parameter.from_dict(data) @@ -339,24 +333,24 @@ def test_dependency_with_descriptor_number(self, clear_global_map): # Expect # Test that functionality still works - assert new_params["z"].value == 7.0 # 3 + 4 - new_x = new_params["x"] - new_y = new_params["y"] + assert new_params['z'].value == 7.0 # 3 + 4 + new_x = new_params['x'] + new_y = new_params['y'] new_x.value = 4.0 - assert new_params["z"].value == 8.0 # 4 + 4 + assert new_params['z'].value == 8.0 # 4 + 4 new_y.value = 6.0 - assert new_params["z"].value == 10.0 # 4 + 6 + assert new_params['z'].value == 10.0 # 4 + 6 def test_get_parameters_with_pending_dependencies(self, clear_global_map): """Test utility function for finding parameters with pending dependencies.""" # Create parameters - a = Parameter(name="a", value=1.0, unit="m") + a = Parameter(name='a', value=1.0, unit='m') b = Parameter.from_dependency( - name="b", dependency_expression="2 * a", dependency_map={"a": a}, unit="m" + name='b', dependency_expression='2 * a', dependency_map={'a': a}, unit='m' ) # Serialize and deserialize - params_data = {"a": a.as_dict(), "b": b.as_dict()} + params_data = {'a': a.as_dict(), 'b': b.as_dict()} global_object.map._clear() new_params = {} for name, data in params_data.items(): @@ -366,8 +360,8 @@ def test_get_parameters_with_pending_dependencies(self, clear_global_map): pending = get_parameters_with_pending_dependencies(new_params) assert len(pending) == 1 - assert pending[0].name == "b" - assert hasattr(pending[0], "_pending_dependency_string") + assert pending[0].name == 'b' + assert hasattr(pending[0], '_pending_dependency_string') # After resolution, should be empty resolve_all_parameter_dependencies(new_params) @@ -376,9 +370,9 @@ def test_get_parameters_with_pending_dependencies(self, clear_global_map): def test_error_handling_missing_dependency(self, clear_global_map): """Test error handling when dependency cannot be resolved.""" - a = Parameter(name="a", value=1.0, unit="m") + a = Parameter(name='a', value=1.0, unit='m') b = Parameter.from_dependency( - name="b", dependency_expression="2 * a", dependency_map={"a": a}, unit="m" + name='b', dependency_expression='2 * a', dependency_map={'a': a}, unit='m' ) # Serialize b but not a @@ -389,9 +383,7 @@ def test_error_handling_missing_dependency(self, clear_global_map): new_b = Parameter.from_dict(b_data) # Should raise error when trying to resolve - with pytest.raises( - ValueError, match="Cannot find parameter with serializer_id" - ): + with pytest.raises(ValueError, match='Cannot find parameter with serializer_id'): new_b.resolve_pending_dependencies() def test_backward_compatibility_base_deserializer(self, clear_global_map): @@ -399,9 +391,9 @@ def test_backward_compatibility_base_deserializer(self, clear_global_map): from easyscience.io.serializer_dict import SerializerDict # Create dependent parameter - a = Parameter(name="a", value=2.0, unit="m") + a = Parameter(name='a', value=2.0, unit='m') b = Parameter.from_dependency( - name="b", dependency_expression="3 * a", dependency_map={"a": a}, unit="m" + name='b', dependency_expression='3 * a', dependency_map={'a': a}, unit='m' ) # Use base serializer path (SerializerDict.decode) @@ -413,31 +405,31 @@ def test_backward_compatibility_base_deserializer(self, clear_global_map): # Should be a valid Parameter (but without dependency resolution) assert isinstance(deserialized, Parameter) - assert deserialized.name == "b" + assert deserialized.name == 'b' assert deserialized.independent is True # Base path doesn't handle dependencies @pytest.mark.parametrize( - "order", - [["x", "y", "z"], ["z", "x", "y"], ["y", "z", "x"], ["z", "y", "x"]], + 'order', + [['x', 'y', 'z'], ['z', 'x', 'y'], ['y', 'z', 'x'], ['z', 'y', 'x']], ids=[ - "normal_order", - "dependent_first", - "mixed_order", - "dependent_first_reverse", + 'normal_order', + 'dependent_first', + 'mixed_order', + 'dependent_first_reverse', ], ) def test_serializer_id_system_order_independence(self, clear_global_map, order): """Test that dependency IDs allow parameters to be loaded in any order.""" # WHEN # Create parameters with dependencies - x = Parameter(name="x", value=5.0, unit="m", min=0, max=20) - y = Parameter(name="y", value=10.0, unit="m", min=0, max=30) + x = Parameter(name='x', value=5.0, unit='m', min=0, max=20) + y = Parameter(name='y', value=10.0, unit='m', min=0, max=30) z = Parameter.from_dependency( - name="z", - dependency_expression="x * y", - dependency_map={"x": x, "y": y}, - unit="m^2", + name='z', + dependency_expression='x * y', + dependency_map={'x': x, 'y': y}, + unit='m^2', ) # Verify original functionality @@ -448,13 +440,13 @@ def test_serializer_id_system_order_independence(self, clear_global_map, order): y_dep_id = y._DescriptorNumber__serializer_id # Serialize all parameters - params_data = {"x": x.as_dict(), "y": y.as_dict(), "z": z.as_dict()} + params_data = {'x': x.as_dict(), 'y': y.as_dict(), 'z': z.as_dict()} # Verify dependency IDs are in serialized data - assert params_data["x"]["__serializer_id"] == x_dep_id - assert params_data["y"]["__serializer_id"] == y_dep_id - assert "__serializer_id" not in params_data["z"] - assert "_dependency_map_serializer_ids" in params_data["z"] + assert params_data['x']['__serializer_id'] == x_dep_id + assert params_data['y']['__serializer_id'] == y_dep_id + assert '__serializer_id' not in params_data['z'] + assert '_dependency_map_serializer_ids' in params_data['z'] # THEN global_object.map._clear() @@ -466,41 +458,41 @@ def test_serializer_id_system_order_independence(self, clear_global_map, order): # EXPECT # Verify dependency IDs are preserved - assert new_params["x"]._DescriptorNumber__serializer_id == x_dep_id - assert new_params["y"]._DescriptorNumber__serializer_id == y_dep_id + assert new_params['x']._DescriptorNumber__serializer_id == x_dep_id + assert new_params['y']._DescriptorNumber__serializer_id == y_dep_id # Resolve dependencies resolve_all_parameter_dependencies(new_params) # Verify functionality regardless of loading order - assert new_params["z"].independent is False - assert new_params["z"].value == 50.0 + assert new_params['z'].independent is False + assert new_params['z'].value == 50.0 # Test dependency updates still work - new_params["x"].value = 6.0 - assert new_params["z"].value == 60.0 # 6 * 10 + new_params['x'].value = 6.0 + assert new_params['z'].value == 60.0 # 6 * 10 - new_params["y"].value = 8.0 - assert new_params["z"].value == 48.0 # 6 * 8 + new_params['y'].value = 8.0 + assert new_params['z'].value == 48.0 # 6 * 8 def test_deserialize_and_resolve_parameters_helper(self, clear_global_map): """Test the convenience helper function for deserialization and dependency resolution.""" # Create test parameters with dependencies - a = Parameter(name="a", value=2.0, unit="m", min=0, max=10) - b = Parameter(name="b", value=3.0, unit="m", min=0, max=10) + a = Parameter(name='a', value=2.0, unit='m', min=0, max=10) + b = Parameter(name='b', value=3.0, unit='m', min=0, max=10) c = Parameter.from_dependency( - name="c", - dependency_expression="a + b", - dependency_map={"a": a, "b": b}, - unit="m", + name='c', + dependency_expression='a + b', + dependency_map={'a': a, 'b': b}, + unit='m', ) # Verify original dependency works assert c.value == 5.0 # 2 + 3 # Serialize all parameters - params_data = {"a": a.as_dict(), "b": b.as_dict(), "c": c.as_dict()} + params_data = {'a': a.as_dict(), 'b': b.as_dict(), 'c': c.as_dict()} # Clear global map global_object.map._clear() @@ -510,27 +502,27 @@ def test_deserialize_and_resolve_parameters_helper(self, clear_global_map): # Verify all parameters are correctly deserialized and dependencies resolved assert len(new_params) == 3 - assert "a" in new_params - assert "b" in new_params - assert "c" in new_params + assert 'a' in new_params + assert 'b' in new_params + assert 'c' in new_params # Check that independent parameters work - assert new_params["a"].name == "a" - assert new_params["a"].value == 2.0 - assert new_params["a"].independent is True + assert new_params['a'].name == 'a' + assert new_params['a'].value == 2.0 + assert new_params['a'].independent is True - assert new_params["b"].name == "b" - assert new_params["b"].value == 3.0 - assert new_params["b"].independent is True + assert new_params['b'].name == 'b' + assert new_params['b'].value == 3.0 + assert new_params['b'].independent is True # Check that dependent parameter is properly resolved - assert new_params["c"].name == "c" - assert new_params["c"].value == 5.0 # 2 + 3 - assert new_params["c"].independent is False + assert new_params['c'].name == 'c' + assert new_params['c'].value == 5.0 # 2 + 3 + assert new_params['c'].independent is False # Verify dependency still works after helper function - new_params["a"].value = 10.0 - assert new_params["c"].value == 13.0 # 10 + 3 + new_params['a'].value = 10.0 + assert new_params['c'].value == 13.0 # 10 + 3 # Verify no pending dependencies remain pending = get_parameters_with_pending_dependencies(new_params) diff --git a/tests/unit_tests/__init__.py b/tests/unit_tests/__init__.py deleted file mode 100644 index 462d95af..00000000 --- a/tests/unit_tests/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause -# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause -# © 2025 Contributors to the EasyScience project - diff --git a/tests/unit_tests/io/test_serializer_component.py b/tests/unit_tests/io/test_serializer_component.py deleted file mode 100644 index 80994b4d..00000000 --- a/tests/unit_tests/io/test_serializer_component.py +++ /dev/null @@ -1,97 +0,0 @@ - -import numpy as np -from copy import deepcopy -from typing import Type - -import pytest - -import easyscience -from easyscience import DescriptorNumber -from easyscience import Parameter - -dp_param_dict = { - "argnames": "dp_kwargs, dp_cls", - "argvalues": ( - [ - { - "@module": DescriptorNumber.__module__, - "@class": DescriptorNumber.__name__, - "@version": easyscience.__version__, - "name": "test", - "value": 1.0, - "variance": None, - "unit": "dimensionless", - "description": "", - "url": "", - "display_name": "test", - }, - DescriptorNumber, - ], - [ - { - "@module": Parameter.__module__, - "@class": Parameter.__name__, - "@version": easyscience.__version__, - "name": "test", - "unit": "km", - "value": 1.0, - "variance": 0.0, - "min": -np.inf, - "max": np.inf, - "fixed": False, - "url": "https://www.boo.com", - "description": "", - "display_name": "test", - }, - Parameter, - ], - ), - "ids": ["DescriptorNumber", "Parameter"], -} - -_skip_opt = [[], None] + [ - k for k in dp_param_dict["argvalues"][0][0].keys() if k[0] != "@" -] -skip_dict = { - "argnames": "skip", - "argvalues": _skip_opt, - "ids": ["skip_" + str(opt) for opt in _skip_opt], -} - - -def check_dict(check, item): - if isinstance(check, dict) and isinstance(item, dict): - for key in check.keys(): - assert key in item.keys() - check_dict(check[key], item[key]) - else: - assert isinstance(item, type(check)) - assert item == check - - -@pytest.mark.parametrize(**skip_dict) -@pytest.mark.parametrize(**dp_param_dict) -def test_variable_as_dict_methods(dp_kwargs: dict, dp_cls: Type[DescriptorNumber], skip): - data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} - - obj = dp_cls(**data_dict) - - dp_kwargs = deepcopy(dp_kwargs) - - if isinstance(skip, str): - del dp_kwargs[skip] - - if not isinstance(skip, list): - skip = [skip] - - enc = obj.as_dict(skip=skip) - - expected_keys = set(dp_kwargs.keys()) - obtained_keys = set(enc.keys()) - - dif = expected_keys.difference(obtained_keys) - - assert len(dif) == 0 - - check_dict(dp_kwargs, enc) - diff --git a/tests/unit_tests/legacy/test_dict.py b/tests/unit_tests/legacy/test_dict.py deleted file mode 100644 index 70af9d78..00000000 --- a/tests/unit_tests/legacy/test_dict.py +++ /dev/null @@ -1,156 +0,0 @@ - -# from copy import deepcopy -# from typing import Type - -# import pytest - -# from easyscience.io.dict import DataDictSerializer -# from easyscience.io.dict import DictSerializer -# from easyscience.variable import DescriptorNumber -# from easyscience.base_classes import BaseObj - -# from .test_core import check_dict -# from .test_core import dp_param_dict -# from .test_core import skip_dict -# from easyscience import global_object - - -# def recursive_remove(d, remove_keys: list) -> dict: -# """ -# Remove keys from a dictionary. -# """ -# if not isinstance(remove_keys, list): -# remove_keys = [remove_keys] -# if isinstance(d, dict): -# dd = {} -# for k in d.keys(): -# if k not in remove_keys: -# dd[k] = recursive_remove(d[k], remove_keys) -# return dd -# else: -# return d - - -# ######################################################################################################################## -# # TESTING ENCODING -# ######################################################################################################################## -# @pytest.mark.parametrize(**skip_dict) -# @pytest.mark.parametrize(**dp_param_dict) -# def test_variable_DictSerializer(dp_kwargs: dict, dp_cls: Type[DescriptorNumber], skip): -# data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} - -# obj = dp_cls(**data_dict) - -# dp_kwargs = deepcopy(dp_kwargs) - -# if isinstance(skip, str): -# del dp_kwargs[skip] - -# if not isinstance(skip, list): -# skip = [skip] - -# enc = obj.encode(skip=skip, encoder=DictSerializer) - -# expected_keys = set(dp_kwargs.keys()) -# obtained_keys = set(enc.keys()) - -# dif = expected_keys.difference(obtained_keys) - -# assert len(dif) == 0 - -# check_dict(dp_kwargs, enc) - - -# @pytest.mark.parametrize(**skip_dict) -# @pytest.mark.parametrize(**dp_param_dict) -# def test_variable_DataDictSerializer(dp_kwargs: dict, dp_cls: Type[DescriptorNumber], skip): -# data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} - -# obj = dp_cls(**data_dict) - -# if isinstance(skip, str): -# del data_dict[skip] - -# if not isinstance(skip, list): -# skip = [skip] - -# enc_d = obj.encode(skip=skip, encoder=DataDictSerializer) - -# expected_keys = set(data_dict.keys()) -# obtained_keys = set(enc_d.keys()) - -# dif = expected_keys.difference(obtained_keys) - -# assert len(dif) == 0 - -# check_dict(data_dict, enc_d) - - -# ######################################################################################################################## -# # TESTING DECODING -# ######################################################################################################################## -# @pytest.mark.parametrize(**dp_param_dict) -# def test_variable_DictSerializer_decode(dp_kwargs: dict, dp_cls: Type[DescriptorNumber]): -# data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} - -# obj = dp_cls(**data_dict) - -# enc = obj.encode(encoder=DictSerializer) -# global_object.map._clear() -# dec = dp_cls.decode(enc, decoder=DictSerializer) - -# for k in data_dict.keys(): -# if hasattr(obj, k) and hasattr(dec, k): -# assert getattr(obj, k) == getattr(dec, k) -# else: -# raise AttributeError(f"{k} not found in decoded object") - - -# @pytest.mark.parametrize(**dp_param_dict) -# def test_variable_DictSerializer_from_dict(dp_kwargs: dict, dp_cls: Type[DescriptorNumber]): -# data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} - -# obj = dp_cls(**data_dict) - -# enc = obj.encode(encoder=DictSerializer) -# global_object.map._clear() -# dec = dp_cls.from_dict(enc) - -# for k in data_dict.keys(): -# if hasattr(obj, k) and hasattr(dec, k): -# assert getattr(obj, k) == getattr(dec, k) -# else: -# raise AttributeError(f"{k} not found in decoded object") - - -# @pytest.mark.parametrize(**dp_param_dict) -# def test_variable_DataDictSerializer_decode(dp_kwargs: dict, dp_cls: Type[DescriptorNumber]): -# data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} - -# obj = dp_cls(**data_dict) - -# enc = obj.encode(encoder=DataDictSerializer) -# with pytest.raises(NotImplementedError): -# dec = obj.decode(enc, decoder=DataDictSerializer) - - -# def test_group_encode(): -# d0 = DescriptorNumber("a", 0) -# d1 = DescriptorNumber("b", 1) - -# from easyscience.base_classes import BaseCollection - -# b = BaseCollection("test", d0, d1) -# d = b.as_dict() -# assert isinstance(d["data"], list) - - -# def test_group_encode2(): -# d0 = DescriptorNumber("a", 0) -# d1 = DescriptorNumber("b", 1) - -# from easyscience.base_classes import BaseCollection - -# b = BaseObj("outer", b=BaseCollection("test", d0, d1)) -# d = b.as_dict() -# assert isinstance(d["b"], dict) \ No newline at end of file diff --git a/tests/unit_tests/legacy/test_json.py b/tests/unit_tests/legacy/test_json.py deleted file mode 100644 index 651bd950..00000000 --- a/tests/unit_tests/legacy/test_json.py +++ /dev/null @@ -1,123 +0,0 @@ - -# import json -# from copy import deepcopy -# from typing import Type - -# import pytest - -# from easyscience.io.json import JsonDataSerializer -# from easyscience.io.json import JsonSerializer -# from easyscience.variable import DescriptorNumber - -# from .test_core import check_dict -# from .test_core import dp_param_dict -# from .test_core import skip_dict -# from easyscience import global_object - - -# def recursive_remove(d, remove_keys: list) -> dict: -# """ -# Remove keys from a dictionary. -# """ -# if not isinstance(remove_keys, list): -# remove_keys = [remove_keys] -# if isinstance(d, dict): -# dd = {} -# for k in d.keys(): -# if k not in remove_keys: -# dd[k] = recursive_remove(d[k], remove_keys) -# return dd -# else: -# return d - - -# ######################################################################################################################## -# # TESTING ENCODING -# ######################################################################################################################## -# @pytest.mark.parametrize(**skip_dict) -# @pytest.mark.parametrize(**dp_param_dict) -# def test_variable_DictSerializer(dp_kwargs: dict, dp_cls: Type[DescriptorNumber], skip): -# data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} - -# obj = dp_cls(**data_dict) - -# dp_kwargs = deepcopy(dp_kwargs) - -# if isinstance(skip, str): -# del dp_kwargs[skip] - -# if not isinstance(skip, list): -# skip = [skip] - -# enc = obj.encode(skip=skip, encoder=JsonSerializer) -# assert isinstance(enc, str) - -# # We can test like this as we don't have "complex" objects yet -# dec = json.loads(enc) -# expected_keys = set(dp_kwargs.keys()) -# obtained_keys = set(dec.keys()) - -# dif = expected_keys.difference(obtained_keys) - -# assert len(dif) == 0 - -# check_dict(dp_kwargs, dec) - - -# @pytest.mark.parametrize(**skip_dict) -# @pytest.mark.parametrize(**dp_param_dict) -# def test_variable_DataDictSerializer(dp_kwargs: dict, dp_cls: Type[DescriptorNumber], skip): -# data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} - -# obj = dp_cls(**data_dict) - -# if isinstance(skip, str): -# del data_dict[skip] - -# if not isinstance(skip, list): -# skip = [skip] - -# enc = obj.encode(skip=skip, encoder=JsonDataSerializer) -# assert isinstance(enc, str) -# enc_d = json.loads(enc) - -# expected_keys = set(data_dict.keys()) -# obtained_keys = set(enc_d.keys()) - -# dif = expected_keys.difference(obtained_keys) - -# assert len(dif) == 0 - -# check_dict(data_dict, enc_d) - -# # ######################################################################################################################## -# # # TESTING DECODING -# # ######################################################################################################################## -# @pytest.mark.parametrize(**dp_param_dict) -# def test_variable_DictSerializer_decode(dp_kwargs: dict, dp_cls: Type[DescriptorNumber]): -# data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} - -# obj = dp_cls(**data_dict) - -# enc = obj.encode(encoder=JsonSerializer) -# global_object.map._clear() -# assert isinstance(enc, str) -# dec = obj.decode(enc, decoder=JsonSerializer) - -# for k in data_dict.keys(): -# if hasattr(obj, k) and hasattr(dec, k): -# assert getattr(obj, k) == getattr(dec, k) -# else: -# raise AttributeError(f"{k} not found in decoded object") - - -# @pytest.mark.parametrize(**dp_param_dict) -# def test_variable_DataDictSerializer_decode(dp_kwargs: dict, dp_cls: Type[DescriptorNumber]): -# data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} - -# obj = dp_cls(**data_dict) - -# enc = obj.encode(encoder=JsonDataSerializer) -# global_object.map._clear() -# with pytest.raises(NotImplementedError): -# dec = obj.decode(enc, decoder=JsonDataSerializer) diff --git a/tests/unit_tests/legacy/test_xml.py b/tests/unit_tests/legacy/test_xml.py deleted file mode 100644 index 7094de85..00000000 --- a/tests/unit_tests/legacy/test_xml.py +++ /dev/null @@ -1,111 +0,0 @@ - -# import sys -# import xml.etree.ElementTree as ET -# from copy import deepcopy -# from typing import Type - -# import pytest - -# from easyscience.legacy.xml import XMLSerializer -# from easyscience.variable import DescriptorNumber - -# from ..io.test_core import dp_param_dict -# from ..io.test_core import skip_dict -# from easyscience import global_object - -# def recursive_remove(d, remove_keys: list) -> dict: -# """ -# Remove keys from a dictionary. -# """ -# if not isinstance(remove_keys, list): -# remove_keys = [remove_keys] -# if isinstance(d, dict): -# dd = {} -# for k in d.keys(): -# if k not in remove_keys: -# dd[k] = recursive_remove(d[k], remove_keys) -# return dd -# else: -# return d - - -# def recursive_test(testing_obj, reference_obj): -# for i, (k, v) in enumerate(testing_obj.items()): -# if isinstance(v, dict): -# recursive_test(v, reference_obj[i]) -# else: -# assert v == XMLSerializer.string_to_variable(reference_obj[i].text) - - -# ######################################################################################################################## -# # TESTING ENCODING -# ######################################################################################################################## -# @pytest.mark.parametrize(**skip_dict) -# @pytest.mark.parametrize(**dp_param_dict) -# def test_variable_XMLDictSerializer(dp_kwargs: dict, dp_cls: Type[DescriptorNumber], skip): -# data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} - -# obj = dp_cls(**data_dict) - -# dp_kwargs = deepcopy(dp_kwargs) - -# if isinstance(skip, str): -# del dp_kwargs[skip] - -# if not isinstance(skip, list): -# skip = [skip] - -# enc = obj.encode(skip=skip, encoder=XMLSerializer) -# ref_encode = obj.encode(skip=skip) -# assert isinstance(enc, str) -# data_xml = ET.XML(enc) -# assert data_xml.tag == "data" -# recursive_test(data_xml, ref_encode) - -# # ######################################################################################################################## -# # # TESTING DECODING -# # ######################################################################################################################## -# @pytest.mark.parametrize(**dp_param_dict) -# def test_variable_XMLDictSerializer_decode(dp_kwargs: dict, dp_cls: Type[DescriptorNumber]): -# data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != "@"} - -# obj = dp_cls(**data_dict) - -# enc = obj.encode(encoder=XMLSerializer) -# assert isinstance(enc, str) -# data_xml = ET.XML(enc) -# assert data_xml.tag == "data" -# global_object.map._clear() -# dec = dp_cls.decode(enc, decoder=XMLSerializer) - -# for k in data_dict.keys(): -# if hasattr(obj, k) and hasattr(dec, k): -# assert getattr(obj, k) == getattr(dec, k) -# else: -# raise AttributeError(f"{k} not found in decoded object") - - -# def test_slow_encode(): - -# if sys.version_info < (3, 9): -# pytest.skip("This test is only for python 3.9+") - -# a = {"a": [1, 2, 3]} -# slow_xml = XMLSerializer().encode(a, fast=False) -# reference = """ -# 1 -# 2 -# 3 -# """ -# assert slow_xml == reference - - -# def test_include_header(): - -# if sys.version_info < (3, 9): -# pytest.skip("This test is only for python 3.9+") - -# a = {"a": [1, 2, 3]} -# header_xml = XMLSerializer().encode(a, use_header=True) -# reference = '?xml version="1.0" encoding="UTF-8"?\n\n 1\n 2\n 3\n' -# assert header_xml == reference diff --git a/tests/unit_tests/models/__init__.py b/tests/unit_tests/models/__init__.py deleted file mode 100644 index bb769856..00000000 --- a/tests/unit_tests/models/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -# © 2025 Contributors to the EasyScience project - diff --git a/tests/unit_tests/variable/__init__.py b/tests/unit_tests/variable/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/unit_tests/variable/test_descriptor_array.py b/tests/unit_tests/variable/test_descriptor_array.py deleted file mode 100644 index 695f5fe2..00000000 --- a/tests/unit_tests/variable/test_descriptor_array.py +++ /dev/null @@ -1,1356 +0,0 @@ -import pytest -from unittest.mock import MagicMock -import scipp as sc -from scipp import UnitError -from scipp.testing import assert_identical - -import numpy as np - -from easyscience.variable import DescriptorArray -from easyscience import DescriptorNumber -from easyscience import global_object - -class TestDescriptorArray: - @pytest.fixture - def descriptor(self): - descriptor = DescriptorArray( - name="name", - value=[[1., 2.], [3., 4.]], - unit="m", - variance=[[0.1, 0.2], [0.3, 0.4]], - description="description", - url="url", - display_name="display_name", - parent=None, - ) - return descriptor - - @pytest.fixture - def descriptor_dimensionless(self): - descriptor = DescriptorArray( - name="name", - value=[[1., 2.], [3., 4.], [5., 6.]], - unit="dimensionless", - variance=[[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]], - description="description", - url="url", - display_name="display_name", - parent=None, - ) - return descriptor - - @pytest.fixture - def clear(self): - global_object.map._clear() - - def test_init(self, descriptor: DescriptorArray): - # When Then Expect - assert np.array_equal(descriptor._array.values,np.array([[1., 2.], [3., 4.]])) - assert descriptor._array.unit == "m" - assert np.array_equal(descriptor._array.variances, np.array([[0.1, 0.2], [0.3, 0.4]])) - - # From super - assert descriptor._name == "name" - assert descriptor._description == "description" - assert descriptor._url == "url" - assert descriptor._display_name == "display_name" - - def test_init_sc_unit(self): - # When Then - descriptor = DescriptorArray( - name="name", - value=[[1., 2.], [3., 4.]], - unit=sc.units.Unit("m"), - variance=[[0.1, 0.2], [0.3, 0.4]], - description="description", - url="url", - display_name="display_name", - parent=None, - ) - - # Expect - assert np.array_equal(descriptor._array.values,np.array([[1., 2.], [3., 4.]])) - assert descriptor._array.unit == "m" - assert np.array_equal(descriptor._array.variances, np.array([[0.1, 0.2], [0.3, 0.4]])) - - def test_init_sc_unit_unknown(self): - # When Then Expect - with pytest.raises(UnitError): - DescriptorArray( - name="name", - value=[[1., 2.], [3., 4.]], - unit="unknown", - variance=[[0.1, 0.2], [0.3, 0.4]], - description="description", - url="url", - display_name="display_name", - parent=None, - ) - - @pytest.mark.parametrize("value", [True, "string"]) - def test_init_value_type_exception(self, value): - # When - - # Then Expect - with pytest.raises(TypeError): - DescriptorArray( - name="name", - value=value, - unit="m", - variance=[[0.1, 0.2], [0.3, 0.4]], - description="description", - url="url", - display_name="display_name", - parent=None, - ) - - def test_init_variance_exception(self): - # When - variance=[[-0.1, -0.2], [-0.3, -0.4]] - # Then Expect - with pytest.raises(ValueError): - DescriptorArray( - name="name", - value=[[1., 2.], [3., 4.]], - unit="m", - variance=variance, - description="description", - url="url", - display_name="display_name", - parent=None, - ) - - # test from_scipp - def test_from_scipp(self): - # When - full_value = sc.array(dims=['row','column'],values=[[1,2],[3,4]], unit='m') - # Then - descriptor = DescriptorArray.from_scipp(name="name", full_value=full_value) - - # Expect - assert np.array_equal(descriptor._array.values,[[1,2],[3,4]]) - assert descriptor._array.unit == "m" - assert descriptor._array.variances == None - - # @pytest.mark.parametrize("full_value", [sc.array(values=[1,2], dimensions=["x"]), sc.array(values=[[1], [2]], dims=["x","y"]), object(), 1, "string"], ids=["1D", "2D", "object", "int", "string"]) - # def test_from_scipp_type_exception(self, full_value): - # # When Then Expect - # with pytest.raises(TypeError): - # DescriptorArray.from_scipp(name="name", full_value=full_value) - - def test_get_full_value(self, descriptor: DescriptorArray): - # When Then Expect - other = sc.array(dims=('dim0','dim1'), - values=[[1.0, 2.0], [3.0, 4.0]], - unit='m', - variances=[[0.1, 0.2], [0.3, 0.4]]) - assert_identical(descriptor.full_value, other) - - def test_set_full_value(self, descriptor: DescriptorArray): - with pytest.raises(AttributeError): - descriptor.full_value = sc.array(dims=['row','column'],values=[[1,2],[3,4]], unit='s') - - def test_unit(self, descriptor: DescriptorArray): - # When Then Expect - assert descriptor.unit == 'm' - - def test_set_unit(self, descriptor: DescriptorArray): - with pytest.raises(AttributeError): - descriptor.unit = 's' - - def test_convert_unit(self, descriptor: DescriptorArray): - # When Then - descriptor.convert_unit('mm') - - # Expect - assert descriptor._array.unit == 'mm' - assert np.array_equal(descriptor._array.values,[[1000,2000],[3000,4000]]) - assert np.array_equal(descriptor._array.variances,[[100000,200000],[300000,400000]]) - - def test_variance(self, descriptor: DescriptorArray): - # When Then Expect - assert np.array_equal(descriptor._array.variances, np.array([[0.1, 0.2], [0.3, 0.4]])) - - - def test_set_variance(self, descriptor: DescriptorArray): - # When Then - descriptor.variance = [[0.2, 0.3], [0.4, 0.5]] - - # Expect - assert np.array_equal(descriptor.variance, np.array([[0.2, 0.3], [0.4, 0.5]])) - assert np.array_equal(descriptor.error, np.sqrt(np.array([[0.2, 0.3], [0.4, 0.5]]))) - - def test_error(self, descriptor: DescriptorArray): - # When Then Expect - assert np.array_equal(descriptor.error, np.sqrt(np.array([[0.1, 0.2], [0.3, 0.4]]))) - - - def test_set_error(self, descriptor: DescriptorArray): - # When Then - descriptor.error = np.sqrt(np.array([[0.2, 0.3], [0.4, 0.5]])) - # Expect - assert np.allclose(descriptor.error, np.sqrt(np.array([[0.2, 0.3], [0.4, 0.5]]))) - assert np.allclose(descriptor.variance, np.array([[0.2, 0.3], [0.4, 0.5]])) - - - def test_value(self, descriptor: DescriptorArray): - # When Then Expect - assert np.array_equal(descriptor.value, np.array([[1, 2], [3, 4]])) - - def test_set_value(self, descriptor: DescriptorArray): - # When Then - descriptor.value = ([[0.2, 0.3], [0.4, 0.5]]) - # Expect - assert np.array_equal(descriptor._array.values, np.array([[0.2, 0.3], [0.4, 0.5]])) - - def test_repr(self, descriptor: DescriptorArray): - # When Then - repr_str = str(descriptor) - - # Expect - assert repr_str == "" - - def test_copy(self, descriptor: DescriptorArray): - # When Then - descriptor_copy = descriptor.__copy__() - - # Expect - assert type(descriptor_copy) == DescriptorArray - assert np.array_equal(descriptor_copy._array.values, descriptor._array.values) - assert descriptor_copy._array.unit == descriptor._array.unit - - @pytest.mark.parametrize("unit_string, expected", [ - ("1e+9", "dimensionless"), - ("1000", "dimensionless"), - ("10dm^2", "m^2")], - ids=["scientific_notation", "numbers", "unit_prefix"]) - def test_base_unit(self, unit_string, expected): - # When - descriptor = DescriptorArray(name="name", value=[[1.0, 2.0], [3.0, 4.0]], unit=unit_string) - - # Then - base_unit = descriptor._base_unit() - - # Expect - assert base_unit == expected - - @pytest.mark.parametrize("test, expected, raises_warning", [ - (DescriptorNumber("test", 2, "m", 0.01), - DescriptorArray("test + name", - [[3.0, 4.0], [5.0, 6.0]], - "m", - [[0.11, 0.21], [0.31, 0.41]]), - True), - (DescriptorNumber("test", 1, "cm", 10), - DescriptorArray("test + name", - [[1.01, 2.01], [3.01, 4.01]], - "m", - [[0.1010, 0.2010], [0.3010, 0.4010]]), - True), - (DescriptorArray("test", - [[2.0, 3.0], [4.0, -5.0]], - "cm", - [[1.0, 2.0], [3.0, 4.0]]), - DescriptorArray("test + name", - [[1.02, 2.03], [3.04, 3.95]], - "m", - [[0.1001, 0.2002], [0.3003, 0.4004]]), - False), - (DescriptorArray("test", - [[2, 3], [4, -5]], - "cm"), - DescriptorArray("test + name", - [[1.02, 2.03], [3.04, 3.95]], - "m", - [[0.1, 0.2], [0.3, 0.4]]), - False), - ], - ids=["descriptor_number_regular", "descriptor_number_unit_conversion", "array_conversion", "array_conversion_integer"]) - def test_addition(self, descriptor: DescriptorArray, test, expected, raises_warning): - # When Then - if raises_warning: - with pytest.warns(UserWarning) as record: - result = descriptor + test - assert len(record) == 1 - assert 'Correlations introduced' in record[0].message.args[0] - else: - result = descriptor + test - # Expect - assert type(result) == DescriptorArray - assert result.name == result.unique_name - assert np.array_equal(result.value, expected.value) - assert result.unit == expected.unit - assert np.allclose(result.variance, expected.variance) - assert descriptor.unit == 'm' - - @pytest.mark.parametrize("test, expected", [ - ([[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], - DescriptorArray("test", - [[3.0, 5.0], [7.0, -1.0], [11.0, -2.0]], - "dimensionless", - [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])), - (1, - DescriptorArray("test", - [[2.0, 3.0], [4.0, 5.0], [6.0, 7.0]], - "dimensionless", - [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])) - ], - ids=["list", "number"]) - def test_addition_dimensionless(self, descriptor_dimensionless: DescriptorArray, test, expected): - # When Then - result = descriptor_dimensionless + test - # Expect - assert type(result) == DescriptorArray - assert np.array_equal(result.value, expected.value) - assert np.allclose(result.variance, expected.variance) - assert descriptor_dimensionless.unit == 'dimensionless' - - @pytest.mark.parametrize("test, expected, raises_warning", [ - (DescriptorNumber("test", 2, "m", 0.01), - DescriptorArray("test + name", - [[3.0, 4.0], [5.0, 6.0]], - "m", - [[0.11, 0.21], [0.31, 0.41]]), - True), - (DescriptorNumber("test", 1, "cm", 10), - DescriptorArray("test + name", - [[101.0, 201.0], [301.0, 401.0]], - "cm", - [[1010.0, 2010.0], [3010.0, 4010.0]]), - True), - (DescriptorArray("test", - [[2.0, 3.0], [4.0, -5.0]], - "cm", - [[1.0, 2.0], [3.0, 4.0]]), - DescriptorArray("test + name", - [[102.0, 203.0], [304.0, 395.0]], - "cm", - [[1001.0, 2002.0], [3003.0, 4004.0]]), - False), - (DescriptorArray("test", - [[2, 3], [4, -5]], - "cm"), - DescriptorArray("test + name", - [[102.0, 203.0], [304.0, 395.0]], - "cm", - [[1000.0, 2000.0], [3000.0, 4000.0]]), - False), - ], - ids=["descriptor_number_regular", "descriptor_number_unit_conversion", "array_conversion", "array_conversion_integer"]) - def test_reverse_addition(self, descriptor: DescriptorArray, test, expected, raises_warning): - # When Then - if raises_warning: - with pytest.warns(UserWarning) as record: - result = test + descriptor - assert len(record) == 1 - assert 'Correlations introduced' in record[0].message.args[0] - else: - result = test + descriptor - # Expect - assert type(result) == DescriptorArray - assert result.name == result.unique_name - assert np.array_equal(result.value, expected.value) - assert result.unit == expected.unit - assert np.allclose(result.variance, expected.variance) - assert descriptor.unit == 'm' - - @pytest.mark.parametrize("test, expected", [ - ([[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], - DescriptorArray("test", - [[3.0, 5.0], [7.0, -1.0], [11.0, -2.0]], - "dimensionless", - [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])), - (1, - DescriptorArray("test", - [[2.0, 3.0], [4.0, 5.0], [6.0, 7.0]], - "dimensionless", - [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])) - ], - ids=["list", "number"]) - def test_reverse_addition_dimensionless(self, descriptor_dimensionless: DescriptorArray, test, expected): - # When Then - result = test + descriptor_dimensionless - # Expect - assert type(result) == DescriptorArray - assert np.array_equal(result.value, expected.value) - assert np.allclose(result.variance, expected.variance) - assert descriptor_dimensionless.unit == 'dimensionless' - - @pytest.mark.parametrize("test, expected, raises_warning", [ - (DescriptorNumber("test", 2, "m", 0.01), - DescriptorArray("test + name", - [[-1.0, 0.0], [1.0, 2.0]], - "m", - [[0.11, 0.21], [0.31, 0.41]]), - True), - (DescriptorNumber("test", 1, "cm", 10), - DescriptorArray("test + name", - [[0.99, 1.99], [2.99, 3.99]], - "m", - [[0.1010, 0.2010], [0.3010, 0.4010]]), - True), - (DescriptorArray("test", - [[2.0, 3.0], [4.0, -5.0]], - "cm", - [[1.0, 2.0], [3.0, 4.0]]), - DescriptorArray("test + name", - [[0.98, 1.97], [2.96, 4.05]], - "m", - [[0.1001, 0.2002], [0.3003, 0.4004]]), - False), - (DescriptorArray("test", - [[2, 3], [4, -5]], - "cm"), - DescriptorArray("test + name", - [[0.98, 1.97], [2.96, 4.05]], - "m", - [[0.100, 0.200], [0.300, 0.400]]), - False) - ], - ids=["descriptor_number_regular", "descriptor_number_unit_conversion", "array_conversion", "array_conversion_integer"]) - def test_subtraction(self, descriptor: DescriptorArray, test, expected, raises_warning): - # When Then - if raises_warning: - with pytest.warns(UserWarning) as record: - result = descriptor - test - assert len(record) == 1 - assert 'Correlations introduced' in record[0].message.args[0] - else: - result = descriptor - test - # Expect - assert type(result) == DescriptorArray - assert result.name == result.unique_name - assert np.array_equal(result.value, expected.value) - assert result.unit == expected.unit - assert np.allclose(result.variance, expected.variance) - assert descriptor.unit == 'm' - - @pytest.mark.parametrize("test, expected", [ - ([[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], - DescriptorArray("test", - [[-1.0, -1.0], [-1.0, 9.0], [-1, 14.0]], - "dimensionless", - [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])), - (1, - DescriptorArray("test", - [[0.0, 1.0], [2.0, 3.0], [4.0, 5.0]], - "dimensionless", - [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])) - ], - ids=["list", "number"]) - def test_subtraction_dimensionless(self, descriptor_dimensionless: DescriptorArray, test, expected): - # When Then - result = descriptor_dimensionless - test - # Expect - assert type(result) == DescriptorArray - assert np.array_equal(result.value, expected.value) - assert np.allclose(result.variance, expected.variance) - assert descriptor_dimensionless.unit == 'dimensionless' - - @pytest.mark.parametrize("test, expected, raises_warning", [ - (DescriptorNumber("test", 2, "m", 0.01), - DescriptorArray("test + name", - [[1.0, 0.0], [-1.0, -2.0]], - "m", - [[0.11, 0.21], [0.31, 0.41]]), - True), - (DescriptorNumber("test", 1, "cm", 10), - DescriptorArray("test + name", - [[-99.0, -199.0], [-299.0, -399.0]], - "cm", - [[1010.0, 2010.0], [3010.0, 4010.0]]), - True), - (DescriptorArray("test", - [[2.0, 3.0], [4.0, -5.0]], - "cm", - [[1.0, 2.0], [3.0, 4.0]]), - DescriptorArray("test + name", - [[-98.0, -197.0], [-296.0, -405.0]], - "cm", - [[1001.0, 2002.0], [3003.0, 4004.0]]), - False), - (DescriptorArray("test", - [[2, 3], [4, -5]], - "cm"), - DescriptorArray("test + name", - [[-98.0, -197.0], [-296.0, -405.0]], - "cm", - [[1000.0, 2000.0], [3000.0, 4000.0]]), - False) - ], - ids=["descriptor_number_regular", "descriptor_number_unit_conversion", "array_conversion", "array_conversion_integer"]) - def test_reverse_subtraction(self, descriptor: DescriptorArray, test, expected, raises_warning): - # When Then - if raises_warning: - with pytest.warns(UserWarning) as record: - result = test - descriptor - assert len(record) == 1 - assert 'Correlations introduced' in record[0].message.args[0] - else: - result = test - descriptor - # Expect - assert type(result) == DescriptorArray - assert result.name == result.unique_name - assert np.array_equal(result.value, expected.value) - assert result.unit == expected.unit - assert np.allclose(result.variance, expected.variance) - assert descriptor.unit == 'm' - - @pytest.mark.parametrize("test, expected", [ - ([[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], - DescriptorArray("test", - [[1.0, 1.0], [1.0, -9.0], [1.0, -14.0]], - "dimensionless", - [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])), - (1, - DescriptorArray("test", - [[0.0, -1.0], [-2.0, -3.0], [-4.0, -5.0]], - "dimensionless", - [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])) - ], - ids=["list", "number"]) - def test_reverse_subtraction_dimensionless(self, descriptor_dimensionless: DescriptorArray, test, expected): - # When Then - result = test - descriptor_dimensionless - # Expect - assert type(result) == DescriptorArray - assert np.array_equal(result.value, expected.value) - assert np.allclose(result.variance, expected.variance) - assert descriptor_dimensionless.unit == 'dimensionless' - - @pytest.mark.parametrize("test, expected, raises_warning", [ - (DescriptorNumber("test", 2, "m", 0.01), - DescriptorArray("test * name", - [[2.0, 4.0], [6.0, 8.0]], - "m^2", - [[0.41, 0.84], [1.29, 1.76]]), - True), - (DescriptorNumber("test", 1, "cm", 10), - DescriptorArray("test * name", - [[0.01, 0.02], [0.03, 0.04]], - "m^2", - [[0.00101, 0.00402], [0.00903, 0.01604]]), - True), - (DescriptorNumber("test", 1, "kg", 10), - DescriptorArray("test * name", - [[1.0, 2.0], [3.0, 4.0]], - "kg*m", - [[10.1, 40.2], [90.3, 160.4]]), - True), - (DescriptorArray("test", - [[2.0, 3.0], [4.0, -5.0]], - "cm", - [[1.0, 2.0], [3.0, 4.0]]), - DescriptorArray("test * name", - [[0.02, 0.06], [0.12, -0.2]], - "m^2", - [[0.00014, 0.00098], [0.00318, 0.0074]]), - False), - (DescriptorArray("test", - [[2, 3], [4, -5]], - "cm"), - DescriptorArray("test * name", - [[0.02, 0.06], [0.12, -0.2]], - "m^2", - [[0.1 * 2**2 * 1e-4, 0.2 * 3**2 * 1e-4], - [0.3 * 4**2 * 1e-4, 0.4 * 5**2 * 1e-4]]), - False), - ([[2.0, 3.0], [4.0, -5.0]], - DescriptorArray("test * name", - [[2.0, 6.0], [12.0, -20.0]], - "m", - [[0.1 * 2**2, 0.2 * 3**2], - [0.3 * 4**2, 0.4 * 5**2]]), - False), - (2.0, - DescriptorArray("test * name", - [[2.0, 4.0], [6.0, 8.0]], - "m", - [[0.1 * 2**2, 0.2 * 2**2], - [0.3 * 2**2, 0.4 * 2**2]]), - False) - - ], - ids=["descriptor_number_regular", - "descriptor_number_unit_conversion", - "descriptor_number_different_units", - "array_conversion", - "array_conversion_integer", - "list", - "number"]) - def test_multiplication(self, descriptor: DescriptorArray, test, expected, raises_warning): - # When Then - if raises_warning: - with pytest.warns(UserWarning) as record: - result = descriptor * test - assert len(record) == 1 - assert 'Correlations introduced' in record[0].message.args[0] - else: - result = descriptor * test - # Expect - assert type(result) == DescriptorArray - assert result.name == result.unique_name - assert np.array_equal(result.value, expected.value) - assert result.unit == expected.unit - assert np.allclose(result.variance, expected.variance) - assert descriptor.unit == 'm' - - @pytest.mark.parametrize("test, expected", [ - ([[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], - DescriptorArray("test", - [[2.0, 6.0], [12.0, -20.0], [30.0, -48.0]], - "dimensionless", - [[0.4, 1.8], [4.8, 10.0], [18.0, 38.4]])), - (1.5, - DescriptorArray("test", - [[1.5, 3.0], [4.5, 6.0], [7.5, 9.0]], - "dimensionless", - [[0.225, 0.45], [0.675, 0.9], [1.125, 1.35]])) - ], - ids=["list", "number"]) - def test_multiplication_dimensionless(self, descriptor_dimensionless: DescriptorArray, test, expected): - # When Then - result = descriptor_dimensionless * test - # Expect - assert type(result) == DescriptorArray - assert np.array_equal(result.value, expected.value) - assert np.allclose(result.variance, expected.variance) - assert descriptor_dimensionless.unit == 'dimensionless' - - @pytest.mark.parametrize("test, expected, raises_warning", [ - (DescriptorNumber("test", 2, "m", 0.01), - DescriptorArray("test * name", - [[2.0, 4.0], [6.0, 8.0]], - "m^2", - [[0.41, 0.84], [1.29, 1.76]]), - True), - (DescriptorNumber("test", 1, "cm", 10), - DescriptorArray("test * name", - [[100.0, 200.0], [300.0, 400.0]], - "cm^2", - [[101000.0, 402000.0], [903000.0, 1604000.0]]), - True), - (DescriptorNumber("test", 1, "kg", 10), - DescriptorArray("test * name", - [[1.0, 2.0], [3.0, 4.0]], - "kg*m", - [[10.1, 40.2], [90.3, 160.4]]), - True), - (DescriptorArray("test", - [[2.0, 3.0], [4.0, -5.0]], - "cm", - [[1.0, 2.0], [3.0, 4.0]]), - DescriptorArray("test * name", - [[200.0, 600.0], [1200.0, -2000.0]], - "cm^2", - [[14000.0, 98000.0], [318000.0, 740000.0]]), - False), - (DescriptorArray("test", - [[2, 3], [4, -5]], - "cm"), - DescriptorArray("test * name", - [[200.0, 600.0], [1200.0, -2000.0]], - "cm^2", - [[0.1 * 2**2 * 1e4, 0.2 * 3**2 * 1e4], - [0.3 * 4**2 * 1e4, 0.4 * 5**2 * 1e4]]), - False), - ([[2.0, 3.0], [4.0, -5.0]], - DescriptorArray("test * name", - [[2.0, 6.0], [12.0, -20.0]], - "m", - [[0.1 * 2**2, 0.2 * 3**2], - [0.3 * 4**2, 0.4 * 5**2]]), - False), - (2.0, - DescriptorArray("test * name", - [[2.0, 4.0], [6.0, 8.0]], - "m", - [[0.1 * 2**2, 0.2 * 2**2], - [0.3 * 2**2, 0.4 * 2**2]]), - False) - - ], - ids=["descriptor_number_regular", - "descriptor_number_unit_conversion", - "descriptor_number_different_units", - "array_conversion", - "array_conversion_integer", - "list", - "number"]) - def test_reverse_multiplication(self, descriptor: DescriptorArray, test, expected, raises_warning): - # When Then - if raises_warning: - with pytest.warns(UserWarning) as record: - result = test * descriptor - assert len(record) == 1 - assert 'Correlations introduced' in record[0].message.args[0] - else: - result = test * descriptor - # Expect - assert type(result) == DescriptorArray - assert result.name == result.unique_name - assert np.array_equal(result.value, expected.value) - assert result.unit == expected.unit - assert np.allclose(result.variance, expected.variance) - assert descriptor.unit == 'm' - - @pytest.mark.parametrize("test, expected", [ - ([[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], - DescriptorArray("test", - [[2.0, 6.0], [12.0, -20.0], [30.0, -48.0]], - "dimensionless", - [[0.4, 1.8], [4.8, 10.0], [18.0, 38.4]])), - (1.5, - DescriptorArray("test", - [[1.5, 3.0], [4.5, 6.0], [7.5, 9.0]], - "dimensionless", - [[0.225, 0.45], [0.675, 0.9], [1.125, 1.35]])) - ], - ids=["list", "number"]) - def test_reverse_multiplication_dimensionless(self, descriptor_dimensionless: DescriptorArray, test, expected): - # When Then - result = test * descriptor_dimensionless - # Expect - assert type(result) == DescriptorArray - assert np.array_equal(result.value, expected.value) - assert np.allclose(result.variance, expected.variance) - assert descriptor_dimensionless.unit == 'dimensionless' - - @pytest.mark.parametrize("test, expected, raises_warning", [ - (DescriptorNumber("test", 2, "m", 0.01), - DescriptorArray("name / test", - [[1.0/2.0, 2.0/2.0], [3.0/2.0, 4.0/2.0]], - "dimensionless", - [[(0.1 + 0.01 * 1.0**2 / 2.0**2) / 2.0**2, - (0.2 + 0.01 * 2.0**2 / 2.0**2) / 2.0**2], - [(0.3 + 0.01 * 3.0**2 / 2.0**2) / 2.0**2, - (0.4 + 0.01 * 4.0**2 / 2.0**2) / 2.0**2]]), - True), - (DescriptorNumber("test", 1, "cm", 10), - DescriptorArray("name / test", - [[100.0, 200.0], [300.0, 400.0]], - "dimensionless", - [[(0.1 + 10 * 1.0**2 / 1.0**2) / 1.0**2 * 1e4, - (0.2 + 10 * 2.0**2 / 1.0**2) / 1.0**2 * 1e4], - [(0.3 + 10 * 3.0**2 / 1.0**2) / 1.0**2 * 1e4, - (0.4 + 10 * 4.0**2 / 1.0**2) / 1.0**2 * 1e4]]), - True), - (DescriptorNumber("test", 1, "kg", 10), - DescriptorArray("name / test", - [[1.0, 2.0], [3.0, 4.0]], - "m/kg", - [[(0.1 + 10 * 1.0**2 / 1.0**2) / 1.0**2, - (0.2 + 10 * 2.0**2 / 1.0**2) / 1.0**2], - [(0.3 + 10 * 3.0**2 / 1.0**2) / 1.0**2, - (0.4 + 10 * 4.0**2 / 1.0**2) / 1.0**2]]), - True), - (DescriptorArray("test", - [[2.0, 3.0], [4.0, -5.0]], - "cm^2", - [[1.0, 2.0], [3.0, 4.0]]), - DescriptorArray("name / test", - [[1/2 * 1e4, 2/3 * 1e4], [3.0/4.0*1e4, -4.0/5.0 * 1e4]], - "1/m", - [[(0.1 + 1.0 * 1.0**2 / 2.0**2) / 2.0**2 * 1e8, - (0.2 + 2.0 * 2.0**2 / 3.0**2) / 3.0**2 * 1e8], - [(0.3 + 3.0 * 3.0**2 / 4.0**2) / 4.0**2 * 1e8, - (0.4 + 4.0 * 4.0**2 / 5.0**2) / 5.0**2 * 1e8]]), - False), - (DescriptorArray("test", - [[2, 3], [4, -5]], - "cm^2"), - DescriptorArray("name / test", - [[1/2 * 1e4, 2/3 * 1e4], [3.0/4.0*1e4, -4.0/5.0 * 1e4]], - "1/m", - [[(0.1) / 2.0**2 * 1e8, - (0.2) / 3.0**2 * 1e8], - [(0.3) / 4.0**2 * 1e8, - (0.4) / 5.0**2 * 1e8]]), - False), - ([[2.0, 3.0], [4.0, -5.0]], - DescriptorArray("name / name", - [[0.5, 2.0/3.0], [3.0/4.0, -4/5]], - "m", - [[0.1 / 2**2, 0.2 / 3.0**2], - [0.3 / 4**2, 0.4 / 5.0**2]]), - False), - (2.0, - DescriptorArray("name / test", - [[0.5, 1.0], [3.0/2.0, 2.0]], - "m", - [[0.1 / 2.0**2, 0.2 / 2.0**2], - [0.3 / 2.0**2, 0.4 / 2.0**2]]), - False) - ], - ids=["descriptor_number_regular", - "descriptor_number_unit_conversion", - "descriptor_number_different_units", - "array_conversion", - "array_conversion_integer", - "list", - "number"]) - def test_division(self, descriptor: DescriptorArray, test, expected, raises_warning): - # When Then - if raises_warning: - with pytest.warns(UserWarning) as record: - result = descriptor / test - assert len(record) == 1 - assert 'Correlations introduced' in record[0].message.args[0] - else: - result = descriptor / test - # Expect - assert type(result) == DescriptorArray - assert result.name == result.unique_name - assert np.allclose(result.value, expected.value) - assert result.unit == expected.unit - assert np.allclose(result.variance, expected.variance) - assert descriptor.unit == 'm' - - @pytest.mark.parametrize("test, expected", [ - ([[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], - DescriptorArray("test", - [[1.0/2.0, 2.0/3.0], [3.0/4.0, -4.0/5.0], [5.0/6.0, -6.0/8.0]], - "dimensionless", - [[0.1 / 2.0**2, - 0.2 / 3.0**2], - [0.3 / 4.0**2, - 0.4 / 5.0**2], - [0.5 / 6.0**2, - 0.6 / 8.0**2]])), - (2, - DescriptorArray("test", - [[1.0/2.0, 2.0/2.0], [3.0/2.0, 4.0/2.0], [5.0/2.0, 6.0/2.0]], - "dimensionless", - [[0.1 / 2.0**2, - 0.2 / 2.0**2], - [0.3 / 2.0**2, - 0.4 / 2.0**2], - [0.5 / 2.0**2, - 0.6 / 2.0**2]])) - ], - ids=["list", "number"]) - def test_division_dimensionless(self, descriptor_dimensionless: DescriptorArray, test, expected): - # When Then - result = descriptor_dimensionless / test - # Expect - assert type(result) == DescriptorArray - assert np.allclose(result.value, expected.value) - assert np.allclose(result.variance, expected.variance) - assert descriptor_dimensionless.unit == 'dimensionless' - - @pytest.mark.parametrize("test, expected, raises_warning", [ - (DescriptorNumber("test", 2, "m", 0.01), - DescriptorArray("test / name", - [[2.0, 1.0], [2.0/3.0, 0.5]], - "dimensionless", - [[0.41, 0.0525], - [(0.01 + 0.3 * 2**2 / 3.0**2) / 3.0**2, - (0.01 + 0.4 * 2**2 / 4.0**2) / 4.0**2]]), - True), - (DescriptorNumber("test", 1, "cm", 10), - DescriptorArray("test / name", - [[1.0/100.0, 1.0/200.0], [1.0/300.0, 1.0/400.0]], - "dimensionless", - [[1.01e-3, (1e-3 + 0.2 * 0.01**2/2**2) / 2**2], - [(1e-3 + 0.3 * 0.01**2/3**2) / 3**2,(1e-3 + 0.4 * 0.01**2 / 4**2) / 4**2]]), - True), - (DescriptorNumber("test", 1, "kg", 10), - DescriptorArray("test / name", - [[1.0, 0.5], [1.0/3.0, 0.25]], - "kg/m", - [[10.1, ( 10 + 0.2 * 1/2**2 ) / 2**2], - [( 10 + 0.3 * 1/3**2 ) / 3**2, ( 10 + 0.4 * 1/4**2 ) / 4**2 ]]), - True), - (DescriptorArray("test", - [[2.0, 3.0], [4.0, -5.0]], - "cm^2", - [[1.0, 2.0], [3.0, 4.0]]), - DescriptorArray("test / name", - [[2e-4, 1.5e-4], [4.0/3.0*1e-4, -1.25e-4]], - "m", - [[1.4e-8, 6.125e-9], - [( 3.0e-8 + 0.3 * (0.0004)**2 / 3**2 ) / 3**2, - ( 4.0e-8 + 0.4 * (0.0005)**2 / 4**2 ) / 4**2]]), - False), - (DescriptorArray("test", - [[2, 3], [4, -5]], - "cm^2"), - DescriptorArray("test / name", - [[2e-4, 1.5e-4], [4.0/3.0*1e-4, -1.25e-4]], - "m", - [[(0.1 * 2.0**2 / 1.0**2) / 1.0**2 * 1e-8, - (0.2 * 3.0**2 / 2.0**2) / 2.0**2 * 1e-8], - [(0.3 * 4.0**2 / 3.0**2) / 3.0**2 * 1e-8, - (0.4 * 5.0**2 / 4.0**2) / 4.0**2 * 1e-8]]), - False), - ([[2.0, 3.0], [4.0, -5.0]], - DescriptorArray("test / name", - [[2, 1.5], [4.0/3.0, -1.25]], - "1/m", - [[0.1 * 2**2 / 1**4, 0.2 * 3.0**2 / 2.0**4], - [0.3 * 4**2 / 3**4, 0.4 * 5.0**2 / 4.0**4]]), - False), - (2.0, - DescriptorArray("test / name", - [[2, 1.0], [2.0/3.0, 0.5]], - "1/m", - [[0.1 * 2**2 / 1**4, 0.2 * 2.0**2 / 2.0**4], - [0.3 * 2**2 / 3**4, 0.4 * 2.0**2 / 4.0**4]]), - False) - ], - ids=["descriptor_number_regular", - "descriptor_number_unit_conversion", - "descriptor_number_different_units", - "array_conversion", - "array_conversion_integer", - "list", - "number"]) - def test_reverse_division(self, descriptor: DescriptorArray, test, expected, raises_warning): - # When Then - if raises_warning: - with pytest.warns(UserWarning) as record: - result = test / descriptor - assert len(record) == 1 - assert 'Correlations introduced' in record[0].message.args[0] - else: - result = test / descriptor - # Expect - assert type(result) == DescriptorArray - assert result.name == result.unique_name - assert np.allclose(result.value, expected.value) - assert result.unit == expected.unit - assert np.allclose(result.variance, expected.variance) - assert descriptor.unit == 'm' - - @pytest.mark.parametrize("test, expected", [ - ([[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]], - DescriptorArray("test", - [[2.0/1.0, 3.0/2.0], [4.0/3.0, -5.0/4.0], [6.0/5.0, -8.0/6.0]], - "dimensionless", - [[0.1 * 2.0**2, 0.2 * 3.0**2 / 2**4], - [0.3 * 4.0**2 / 3.0**4, 0.4 * 5.0**2 / 4**4], - [0.5 * 6.0**2 / 5**4, 0.6 * 8.0**2 / 6**4]])), - (2, - DescriptorArray("test", - [[2.0, 1.0], [2.0/3.0, 0.5], [2.0/5.0, 1.0/3.0]], - "dimensionless", - [[0.1 * 2.0**2, 0.2 / 2**2], - [0.3 * 2**2 / 3**4, 0.4 * 2**2 / 4**4], - [0.5 * 2**2 / 5**4, 0.6 * 2**2 / 6**4]])) - ], - ids=["list", "number"]) - def test_reverse_division_dimensionless(self, descriptor_dimensionless: DescriptorArray, test, expected): - # When Then - result = test / descriptor_dimensionless - # Expect - assert type(result) == DescriptorArray - assert np.allclose(result.value, expected.value) - assert np.allclose(result.variance, expected.variance) - assert descriptor_dimensionless.unit == 'dimensionless' - - @pytest.mark.parametrize("test", [ - [[2.0, 3.0], [4.0, -5.0], [6.0, 0.0]], - 0.0, - DescriptorNumber("test", 0, "cm", 10), - DescriptorArray("test", - [[1.5, 0.0], [4.5, 6.0], [7.5, 9.0]], - "dimensionless", - [[0.225, 0.45], [0.675, 0.9], [1.125, 1.35]])], - ids=["list", "number", "DescriptorNumber", "DescriptorArray"]) - def test_division_exception(self, descriptor_dimensionless: DescriptorArray, test): - # When Then - with pytest.raises(ZeroDivisionError): - descriptor_dimensionless / test - - # Also test reverse division where `self` is a DescriptorArray with a zero - zero_descriptor = DescriptorArray("test", - [[1.5, 0.0], [4.5, 6.0], [7.5, 0.0]], - "dimensionless", - [[0.225, 0.45], [0.675, 0.9], [1.125, 1.35]]) - with pytest.raises(ZeroDivisionError): - test / zero_descriptor - - @pytest.mark.parametrize("test, expected", [ - (DescriptorNumber("test", 2, "dimensionless"), - DescriptorArray("test ** name", - [[1.0, 4.0], [9.0, 16.0]], - "m^2", - [[4 * 0.1 * 1, 4 * 0.2 * 2**2], - [4 * 0.3 * 3**2, 4 * 0.4 * 4**2]])), - (DescriptorNumber("test", 3, "dimensionless"), - DescriptorArray("test ** name", - [[1.0, 8.0], [27, 64.0]], - "m^3", - [[9 * 0.1, 9 * 0.2 * 2**4], - [9 * 0.3 * 3**4, 9 * 0.4 * 4**4]])), - (DescriptorNumber("test", 0.0, "dimensionless"), - DescriptorArray("test ** name", - [[1.0, 1.0], [1.0, 1.0]], - "dimensionless", - [[0.0, 0.0], [0.0, 0.0]])), - (0.0, - DescriptorArray("test ** name", - [[1.0, 1.0], [1.0, 1.0]], - "dimensionless", - [[0.0, 0.0], [0.0, 0.0]])) - ], - ids=["descriptor_number_squared", - "descriptor_number_cubed", - "descriptor_number_zero", - "number_zero"]) - def test_power(self, descriptor: DescriptorArray, test, expected): - # When Then - result = descriptor ** test - # Expect - assert type(result) == DescriptorArray - assert result.name == result.unique_name - assert np.array_equal(result.value, expected.value) - assert result.unit == expected.unit - assert np.allclose(result.variance, expected.variance) - assert descriptor.unit == 'm' - - @pytest.mark.parametrize("test, expected", [ - (DescriptorNumber("test", 0.1, "dimensionless"), - DescriptorArray("test ** name", - [[1, 2**0.1], [3**0.1, 4**0.1], [5**0.1, 6**0.1]], - "dimensionless", - [[0.1**2 * 0.1 * 1, 0.1**2 * 0.2 * 2**(-1.8)], - [0.1**2 * 0.3 * 3**(-1.8), 0.1**2 * 0.4 * 4**(-1.8)], - [0.1**2 * 0.5 * 5**(-1.8), 0.1**2 * 0.6 * 6**(-1.8)]])), - (DescriptorNumber("test", 2.0, "dimensionless"), - DescriptorArray("test ** name", - [[1.0, 4.0], [9.0, 16.0], [25.0, 36.0]], - "dimensionless", - [[0.4, 3.2], [10.8, 25.6], [50., 86.4]])), - ], - ids=["descriptor_number_fractional", "descriptor_number_integer"]) - def test_power_dimensionless(self, descriptor_dimensionless: DescriptorArray, test, expected): - # When Then - result = descriptor_dimensionless ** test - # Expect - assert type(result) == DescriptorArray - assert result.name == result.unique_name - assert np.allclose(result.value, expected.value) - assert result.unit == expected.unit - assert np.allclose(result.variance, expected.variance) - assert descriptor_dimensionless.unit == 'dimensionless' - - @pytest.mark.parametrize("test, exception", [ - (DescriptorNumber("test", 2, "m"), UnitError), - (DescriptorNumber("test", 2, "dimensionless", 10), ValueError), - (DescriptorNumber("test", np.nan, "dimensionless"), UnitError), - (DescriptorNumber("test", np.nan, "dimensionless"), UnitError), - (DescriptorNumber("test", 1.5, "dimensionless"), UnitError), - (DescriptorNumber("test", 0.5, "dimensionless"), UnitError) # Square roots are not legal - ], - ids=["units", - "variance", - "scipp_nan", - "nan_result", - "non_integer_exponent_on_units", - "square_root_on_units" - ]) - def test_power_exception(self, descriptor: DescriptorArray, test, exception): - # When Then - with pytest.raises(exception): - result = descriptor ** 2 ** test - with pytest.raises(ValueError): - # Exponentiation with an array does not make sense - test ** descriptor - - @pytest.mark.parametrize("test", [ - DescriptorNumber("test", 2, "s"), - DescriptorArray("test", [[1, 2], [3, 4]], "s")], ids=["add_array_to_unit", "incompatible_units"]) - def test_addition_exception(self, descriptor: DescriptorArray, test): - # When Then Expect - with pytest.raises(UnitError): - result = descriptor + test - with pytest.raises(UnitError): - result_reverse = test + descriptor - - @pytest.mark.parametrize("test", [ - DescriptorNumber("test", 2, "s"), - DescriptorArray("test", [[1, 2], [3, 4]], "s")], ids=["add_array_to_unit", "incompatible_units"]) - def test_sub_exception(self, descriptor: DescriptorArray, test): - # When Then Expect - with pytest.raises(UnitError): - result = descriptor - test - with pytest.raises(UnitError): - result_reverse = test - descriptor - - @pytest.mark.parametrize("function", [ - np.sin, - np.cos, - np.exp, - np.add, - np.multiply - ], - ids=["sin", "cos", "exp", "add", "multiply"]) - def test_numpy_ufuncs_exception(self, descriptor_dimensionless, function): - (np.add,np.array([[2.0, 3.0], [4.0, -5.0], [6.0, -8.0]])), - """ - Not implemented ufuncs should return NotImplemented. - """ - test = np.array([[1, 2], [3, 4]]) - with pytest.raises(TypeError) as e: - function(descriptor_dimensionless, test) - assert 'returned NotImplemented from' in str(e) - - def test_negation(self, descriptor): - # When - # Then - result = -descriptor - - # Expect - expected = DescriptorArray( - name="name", - value=[[-1., -2.], [-3., -4.]], - unit="m", - variance=[[0.1, 0.2], [0.3, 0.4]], - description="description", - url="url", - display_name="display_name", - parent=None, - ) - assert type(result) == DescriptorArray - assert result.name == result.unique_name - assert np.array_equal(result.value, expected.value) - assert result.unit == expected.unit - assert np.allclose(result.variance, expected.variance) - assert descriptor.unit == 'm' - - def test_abs(self, descriptor): - # When - negated = DescriptorArray( - name="name", - value=[[-1., -2.], [-3., -4.]], - unit="m", - variance=[[0.1, 0.2], [0.3, 0.4]], - description="description", - url="url", - display_name="display_name", - parent=None, - ) - - # Then - result = abs(negated) - - # Expect - assert type(result) == DescriptorArray - assert result.name == result.unique_name - assert np.array_equal(result.value, descriptor.value) - assert result.unit == descriptor.unit - assert np.allclose(result.variance, descriptor.variance) - assert descriptor.unit == 'm' - - @pytest.mark.parametrize("test, expected", [ - (DescriptorArray("test + name", - [[3.0, 4.0], [5.0, 6.0]], - "m", - [[0.11, 0.21], [0.31, 0.41]]), - DescriptorNumber("test", 9, "m", 0.52)), - (DescriptorArray("test + name", - [[101.0, 201.0], [301.0, 401.0]], - "dimensionless", - [[1010.0, 2010.0], [3010.0, 4010.0]]), - DescriptorNumber("test", 502.0, "dimensionless", 5020.0)), - (DescriptorArray("test", np.ones((9, 9)), "dimensionless", np.ones((9, 9))), - DescriptorNumber("test", 9.0, "dimensionless", 9.0)), - (DescriptorArray("test", np.ones((3, 3, 3)), "dimensionless", np.ones((3, 3, 3))), - DescriptorArray("test", [3., 3., 3.], "dimensionless", [3., 3., 3.,], dimensions=['dim2'])), - (DescriptorArray("test", [[2.0]], "dimensionless"), - DescriptorNumber("test", 2.0, "dimensionless")) - ], - ids=["2d_unit", "2d_dimensionless", "2d_large", "3d_dimensionless", "1d_dimensionless"]) - def test_trace(self, test: DescriptorArray, expected: DescriptorNumber): - result = test.trace() - assert type(result) == type(expected) - assert result.name == result.unique_name - assert np.array_equal(result.value, expected.value) - assert result.unit == expected.unit - if test.variance is not None: - assert np.allclose(result.variance, expected.variance) - if isinstance(expected, DescriptorArray): - assert np.all(result.full_value.dims == expected.full_value.dims) - - @pytest.mark.parametrize("test, expected, dimensions", [ - (DescriptorArray("test", np.ones((3, 3, 4, 5)), "dimensionless", np.ones((3, 3, 4, 5))), - DescriptorArray("test", 3*np.ones((3, 4)), "dimensionless", 3*np.ones((3, 4)), dimensions=['dim0', 'dim2']), - ('dim1', 'dim3')) - ], - ids=["4d"]) - def test_trace_select_dimensions(self, test: DescriptorArray, expected: DescriptorNumber, dimensions): - result = test.trace(dimension1=dimensions[0], dimension2=dimensions[1]) - assert type(result) == type(expected) - assert result.name == result.unique_name - assert np.array_equal(result.value.shape, expected.value.shape) - assert np.array_equal(result.value, expected.value) - assert result.unit == expected.unit - assert np.all(result.full_value.dims == expected.full_value.dims) - - @pytest.mark.parametrize("test,dimensions,message", [ - (DescriptorArray("test", np.ones((3, 3, 3)), "dimensionless", np.ones((3, 3, 3))), - ('dim0', None), - "Either both or none" - ), - (DescriptorArray("test", np.ones((3, 3, 3)), "dimensionless", np.ones((3, 3, 3))), - ('dim0', 'dim0'), - "must be different" - ), - (DescriptorArray("test", np.ones((3, 3, 3)), "dimensionless", np.ones((3, 3, 3))), - ('dim0', 'dim1337'), - "does not exist" - ), - ], - ids=["one_defined_dimension", "same_dimension", "invalid_dimension"]) - def test_trace_exception(self, test: DescriptorArray, dimensions, message): - with pytest.raises(ValueError) as e: - test.trace(dimension1=dimensions[0], dimension2=dimensions[1]) - assert message in str(e) - - def test_slicing(self, descriptor: DescriptorArray): - # When - first_value = descriptor['dim0', 0] - last_value = descriptor['dim0', -1] - second_array = descriptor['dim1', :] - - # Then - assert type(first_value) == DescriptorArray - assert type(last_value) == DescriptorArray - assert type(second_array) == DescriptorArray - - assert first_value.name != descriptor.unique_name - assert last_value.name != descriptor.unique_name - assert second_array.name != descriptor.unique_name - - assert np.array_equal(first_value.full_value.values, descriptor.full_value['dim0', 0].values) - assert np.array_equal(last_value.full_value.values, descriptor.full_value['dim0', -1].values) - assert np.array_equal(second_array.full_value.values, descriptor.full_value['dim1', :].values) - - assert np.array_equal(first_value.full_value.variances, descriptor.full_value['dim0', 0].variances) - assert np.array_equal(last_value.full_value.variances, descriptor.full_value['dim0', -1].variances) - assert np.array_equal(second_array.full_value.variances, descriptor.full_value['dim1', :].variances) - - assert np.array_equal(first_value.full_value.unit, descriptor.unit) - assert np.array_equal(last_value.full_value.unit, descriptor.unit) - assert np.array_equal(second_array.full_value.unit, descriptor.unit) - - def test_slice_deletion(self, descriptor: DescriptorArray): - with pytest.raises(AttributeError) as e: - del descriptor['dim0', 0] - assert 'has no attribute' in str(e) - - @pytest.mark.parametrize("test", [ - 1.0, - [3.0, 4.0, 5.0] - ], - ids=["number", "list"]) - def test_slice_assignment_exception(self, descriptor_dimensionless: DescriptorArray, test): - # When - with pytest.raises(AttributeError) as e: - descriptor_dimensionless['dim0', :] = test - assert "cannot be edited via slicing" in str(e) - - @pytest.mark.parametrize("test, expected", [ - (DescriptorArray("test + name", - [[3.0, 4.0], [5.0, 6.0]], - "m", - [[0.11, 0.21], [0.31, 0.41]]), - DescriptorNumber("test", 18, "m", 1.04)), - (DescriptorArray("test + name", - [[101.0, 201.0], [301.0, 401.0]], - "cm", - [[1010.0, 2010.0], [3010.0, 4010.0]]), - DescriptorNumber("test", 1004.0, "cm", 10040.)), - (DescriptorArray("test", - [[2.0, 3.0]], - "dimensionless", - [[1.0, 2.0]]), - DescriptorNumber("test", 5.0, "dimensionless", 3.0)), - (DescriptorArray("test", - [[2.0, 3.0]], - "dimensionless"), - DescriptorNumber("test", 5.0, "dimensionless")), - ], - ids=["descriptor_array_m", "d=descriptor_array_cm", "descriptor_array_dimensionless", "descriptor_array_dim_varless"]) - def test_sum(self, test, expected): - result = test.sum() - assert type(result) == DescriptorNumber - assert result.name == result.unique_name - assert np.array_equal(result.value, expected.value) - assert result.unit == expected.unit - if test.variance is not None: - assert np.allclose(result.variance, expected.variance) - - @pytest.mark.parametrize("expected, dim", [ - (DescriptorArray("test", - [4.0, 6.0], - "m", - [0.4, 0.6]), - 'dim0'), - (DescriptorArray("test", - [3.0, 7.0], - "m", - [0.3, 0.7]), - 'dim1'), - ], - ids=["descriptor_array_dim0", "descriptor_array_dim1"]) - def test_sum_over_subset(self, descriptor, expected, dim): - result = descriptor.sum(dim) - assert type(result) == type(expected) - assert result.name == result.unique_name - assert np.array_equal(result.value, expected.value) - assert result.unit == expected.unit - assert np.allclose(result.variance, expected.variance) - - @pytest.mark.parametrize("test, dimensions", [ - (DescriptorArray("test", [1.], "dimensionless", [1.]), ['dim0']), - (DescriptorArray("test", [[1., 1.]], "dimensionless", [[1., 1.]]), ['dim0', 'dim1']), - (DescriptorArray("test", [[1.], [1.]], "dimensionless", [[1.], [1.]]), ['dim0', 'dim1']), - (DescriptorArray("test", [[[1., 1., 1.]]], "dimensionless", [[[1., 1., 1.]]]), ['dim0', 'dim1', 'dim2']), - (DescriptorArray("test", [[[1.]], [[1.]], [[1.]]], "dimensionless", [[[1.]], [[1.]], [[1.]]]), ['dim0', 'dim1', 'dim2']), - ], - ids=["1x1", "1x2", "2x1", "1x3", "3x1"]) - def test_array_generate_dimensions(self, test, dimensions): - assert test.dimensions == dimensions - - def test_array_set_dimensions_exception(self, descriptor): - with pytest.raises(ValueError) as e: - descriptor.dimensions = ['too_few'] - assert "must have the same shape" - with pytest.raises(ValueError) as e: - DescriptorArray("test", [[1.]], "m", [[1.]], dimensions=['dim']) - assert "Length of dimensions" in str(e) - - def test_array_set_integer_value(self, descriptor): - """ - Scipp does not convert ints to floats, but values need to be floats for optimization. - """ - # When - descriptor.value = [[1, 2], [3, 4]] - # Then Expect - assert isinstance(descriptor.value[0][0], float) - - def test_array_set_integer_variance(self, descriptor): - # When - descriptor.variance = [[1, 2], [3, 4]] - # Then Expect - assert isinstance(descriptor.variance[0][0], float) - - def test_array_create_with_mixed_integers_and_floats(self): - # When - value = [[1, 2], [3, 4]] - variance = [[0.1, 0.2], [0.3, 0.4]] - # Then Expect - descriptor = DescriptorArray('test', value, 'dimensionless', variance) # Should not raise - assert isinstance(descriptor.value[0][0], float) - assert isinstance(descriptor.variance[0][0], float) - - def test_array_set_dims(self, descriptor): - # When - descriptor.dimensions = ['x', 'y'] - # Then Expect - assert descriptor.dimensions[0] == 'x' - assert descriptor.dimensions[1] == 'y' - assert descriptor.full_value.dims[0] == 'x' - assert descriptor.full_value.dims[1] == 'y' diff --git a/tests/unit_tests/variable/test_descriptor_base.py b/tests/unit_tests/variable/test_descriptor_base.py deleted file mode 100644 index aeeb823e..00000000 --- a/tests/unit_tests/variable/test_descriptor_base.py +++ /dev/null @@ -1,166 +0,0 @@ -import pytest - -from easyscience import global_object -from easyscience.variable.descriptor_base import DescriptorBase - - -class TestDesciptorBase: - @pytest.fixture - def descriptor(self): - # This avoids the error: TypeError: Can't instantiate abstract class DescriptorBase with abstract methods __init__ - DescriptorBase.__abstractmethods__ = set() - DescriptorBase.__repr__ = lambda x: "DescriptorBase" - self.objs_before_new_descriptor = len(global_object.map.created_objs) - descriptor = DescriptorBase( - name="name", - description="description", - url="url", - display_name="display_name", - parent=None, - ) - return descriptor - - @pytest.fixture - def clear(self): - global_object.map._clear() - - @pytest.mark.parametrize("name", [1, True, 1.0, [], {}, (), None, object()], ids=["int", "bool", "float", "list", "dict", "tuple", "None", "object"]) - def test_init_name_type_error(self, name): - # When Then - with pytest.raises(TypeError): - DescriptorBase(name=name, description="description", url="url", display_name="display_name", parent=None) - - @pytest.mark.parametrize("display_name", [1, True, 1.0, [], {}, (), object()], ids=["int", "bool", "float", "list", "dict", "tuple", "object"]) - def test_init_display_name_type_error(self, display_name): - # When Then - with pytest.raises(TypeError): - DescriptorBase(name="name", description="description", url="url", display_name=display_name, parent=None) - - @pytest.mark.parametrize("description", [1, True, 1.0, [], {}, (), object()], ids=["int", "bool", "float", "list", "dict", "tuple", "object"]) - def test_init_description_type_error(self, description): - # When Then - with pytest.raises(TypeError): - DescriptorBase(name="name", description=description, url="url", display_name="display_name", parent=None) - - @pytest.mark.parametrize("url", [1, True, 1.0, [], {}, (), object()], ids=["int", "bool", "float", "list", "dict", "tuple", "object"]) - def test_init_url_type_error(self, url): - # When Then - with pytest.raises(TypeError): - DescriptorBase(name="name", description="description", url=url, display_name="display_name", parent=None) - - def test_init(self, descriptor: DescriptorBase): - assert descriptor._name == "name" - assert descriptor._description == "description" - assert descriptor._url == "url" - assert descriptor._display_name == "display_name" - assert len(global_object.map.created_objs) - self.objs_before_new_descriptor == 1 - - - def test_display_name(self, descriptor: DescriptorBase): - # When Then Expect - assert descriptor.display_name == "display_name" - - def test_display_name_none(self, descriptor: DescriptorBase): - # When - descriptor._display_name = None - # Then Expect - assert descriptor.display_name == "name" - - def test_display_name_setter(self, descriptor: DescriptorBase): - # When - descriptor.display_name = "new_display_name" - # Then Expect - assert descriptor.display_name == "new_display_name" - - @pytest.mark.parametrize("display_name", [1, True, 1.0, [], {}, (), object()], ids=["int", "bool", "float", "list", "dict", "tuple", "object"]) - def test_display_name_setter_type_error(self, descriptor: DescriptorBase, display_name): - # When Then - with pytest.raises(TypeError): - descriptor.display_name = display_name - - def test_name_setter(self, descriptor: DescriptorBase): - # When - descriptor.name = "new_name" - # Then Expect - assert descriptor.name == "new_name" - - @pytest.mark.parametrize("name", [1, True, 1.0, [], {}, (), object(), None], ids=["int", "bool", "float", "list", "dict", "tuple", "object", "None"]) - def test_name_setter_type_error(self, descriptor: DescriptorBase, name): - # When Then - with pytest.raises(TypeError): - descriptor.name = name - - def test_description_setter(self, descriptor: DescriptorBase): - # When - descriptor.description = "new_description" - # Then Expect - assert descriptor.description == "new_description" - - @pytest.mark.parametrize("description", [1, True, 1.0, [], {}, (), object()], ids=["int", "bool", "float", "list", "dict", "tuple", "object"]) - def test_description_setter_type_error(self, descriptor: DescriptorBase, description): - # When Then - with pytest.raises(TypeError): - descriptor.description = description - - def test_url_setter(self, descriptor: DescriptorBase): - # When - descriptor.url = "new_url" - # Then Expect - assert descriptor.url == "new_url" - - @pytest.mark.parametrize("url", [1, True, 1.0, [], {}, (), object()], ids=["int", "bool", "float", "list", "dict", "tuple", "object"]) - def test_url_setter_type_error(self, descriptor: DescriptorBase, url): - # When Then - with pytest.raises(TypeError): - descriptor.url = url - - - @pytest.mark.parametrize("stack_enabled,stack_elements", [(False, 0), (True, 1)]) - def test_set_display_name_without_global_object_stack(self, descriptor: DescriptorBase, stack_enabled, stack_elements): - # When - descriptor.__repr__ = lambda x: "DescriptorBase" - global_object.stack.clear() - global_object.stack._enabled = stack_enabled - - # Then - descriptor.display_name = "new_display_name" - - # Expect - assert descriptor.display_name == "new_display_name" - assert len(global_object.stack.history) == stack_elements - - def test_copy(self, descriptor: DescriptorBase): - # When Then - descriptor_copy = descriptor.__copy__() - - # Expect - assert type(descriptor_copy) == DescriptorBase - assert descriptor_copy._name == descriptor._name - assert descriptor_copy._description == descriptor._description - assert descriptor_copy._url == descriptor._url - assert descriptor_copy._display_name == descriptor._display_name - - def test_unique_name_generator(self, clear, descriptor: DescriptorBase): - # When - second_descriptor = DescriptorBase(name="test", unique_name="DescriptorBase_2") - - # Then - third_descriptor = DescriptorBase(name="test2") - fourth_descriptor = DescriptorBase(name="test3") - - # Expect - assert descriptor.unique_name == "DescriptorBase_0" - assert third_descriptor.unique_name == "DescriptorBase_3" - assert fourth_descriptor.unique_name == "DescriptorBase_4" - - def test_unique_name_change(self, clear, descriptor: DescriptorBase): - # When Then - descriptor.unique_name = "test" - # Expect - assert descriptor.unique_name == "test" - - @pytest.mark.parametrize("input", [2, 2.0, [2], {2}, None]) - def test_unique_name_change_exception(self, input, descriptor: DescriptorBase): - # When Then Expect - with pytest.raises(TypeError): - descriptor.unique_name = input \ No newline at end of file diff --git a/tools/add_spdx.py b/tools/add_spdx.py new file mode 100644 index 00000000..295a7e0d --- /dev/null +++ b/tools/add_spdx.py @@ -0,0 +1,149 @@ +"""Add SPDX headers to Python files. + +- SPDX-FileCopyrightText with the license holder name and organization + URL from ``pyproject.toml`` as well as the file's creation year. +- SPDX-License-Identifier is taken from the project license value in + ``pyproject.toml``. +""" + +from __future__ import annotations + +import argparse +import tomllib +from datetime import datetime +from pathlib import Path +from typing import Optional +from typing import Union + +from git import Repo +from spdx_headers.core import find_repository_root +from spdx_headers.core import get_copyright_info +from spdx_headers.data import load_license_data +from spdx_headers.operations import add_header_to_single_file + +LICENSE_DATABASE = load_license_data() + + +def load_pyproject(repo_path: Union[str, Path]) -> dict: + """Load and return parsed ``pyproject.toml`` data for the + repository. + """ + repo_root = find_repository_root(repo_path) + pyproject_path = repo_root / 'pyproject.toml' + + with open(pyproject_path, 'rb') as file_handle: + return tomllib.load(file_handle) + + +def get_file_creation_year(file_path: Union[str, Path]) -> str: + """Return the year the file was first added to Git history. + + If the year cannot be determined, fall back to the current year. + """ + file_path = Path(file_path) + + repo = Repo(file_path, search_parent_directories=True) + root = Path(repo.working_tree_dir).resolve() + rel_path = file_path.resolve().relative_to(root) + + rel_path_git = rel_path.as_posix() # IMPORTANT for git pathspec + + # Get the year when the file was first added to Git history. + # NOTE: Do not combine `--reverse` with `--max-count=1` here, as it can + # yield an empty result with some Git versions. Instead, get the full + # filtered output and take the first line. + log_output = repo.git.log( + '--follow', + '--diff-filter=A', + '--reverse', + '--format=%ad', + '--date=format:%Y', + '--', + rel_path_git, + ).strip() + + year = log_output.splitlines()[0].strip() if log_output else '' + + return year or str(datetime.now().year) + + +def get_org_url(repo_path: Union[str, Path]) -> str: + """Return the organization URL derived from the repository source + URL. + """ + pyproject_data = load_pyproject(repo_path) + repo_url = pyproject_data['project']['urls']['Source Code'] + return repo_url.rsplit('/', 1)[0] + + +def get_project_license(repo_path: Union[str, Path]) -> str: + """Return the project license value from ``pyproject.toml``.""" + pyproject_data = load_pyproject(repo_path) + return pyproject_data['project']['license'] + + +def get_copyright_holder(repo_path: Union[str, Path]) -> str: + """Return the repository copyright holder name.""" + _, name, _ = get_copyright_info(repo_path) + return name + + +def add_spdx_header( + target_file: Union[str, Path], + *, + license_key: str, + copyright_holder: str, + org_url: str, +) -> None: + """Add SPDX headers.""" + year = get_file_creation_year(target_file) + + add_header_to_single_file( + filepath=target_file, + license_key=license_key, + license_data=LICENSE_DATABASE, + year=year, + name=copyright_holder, + email=org_url, + ) + + +def build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + description='Add SPDX headers to Python files under the given paths.', + ) + parser.add_argument( + 'paths', + nargs='+', + help='Relative paths to scan (e.g. src tests)', + ) + return parser + + +def main(argv: Optional[list[str]] = None) -> int: + parser = build_parser() + args = parser.parse_args(argv) + + repo_path = Path('.').resolve() + license_key = get_project_license(repo_path) + copyright_holder = get_copyright_holder(repo_path) + org_url = get_org_url(repo_path) + + for base_dir in args.paths: + base_path = Path(base_dir) + if not base_path.exists(): + parser.error(f'Path does not exist: {base_dir}') + + for py_file in base_path.rglob('*.py'): + add_spdx_header( + py_file, + license_key=license_key, + copyright_holder=copyright_holder, + org_url=org_url, + ) + + return 0 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/tools/check_spdx.py b/tools/check_spdx.py new file mode 100644 index 00000000..80555ab1 --- /dev/null +++ b/tools/check_spdx.py @@ -0,0 +1,43 @@ +"""Check SPDX headers in Python files.""" + +from __future__ import annotations + +import argparse +from pathlib import Path +from typing import Optional + +from spdx_headers.operations import check_headers + + +def build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + description='Check SPDX headers in Python files under the given paths.', + ) + parser.add_argument( + 'paths', + nargs='+', + help='Relative paths to scan (e.g. src tests)', + ) + return parser + + +def main(argv: Optional[list[str]] = None) -> int: + parser = build_parser() + args = parser.parse_args(argv) + + exit_codes = [] + + for base_dir in args.paths: + base_path = Path(base_dir) + if not base_path.exists(): + parser.error(f'Path does not exist: {base_dir}') + + print('=' * 50) + print(f'Checking SPDX headers in: {base_dir}') + exit_codes.append(check_headers(base_dir)) + + return 0 if all(code == 0 for code in exit_codes) else 1 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/tools/remove_spdx.py b/tools/remove_spdx.py new file mode 100644 index 00000000..50e547a7 --- /dev/null +++ b/tools/remove_spdx.py @@ -0,0 +1,39 @@ +"""Remove SPDX headers from Python files.""" + +from __future__ import annotations + +import argparse +from pathlib import Path +from typing import Optional + +from spdx_headers.operations import remove_header_from_py_files + + +def build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + description='Remove SPDX headers from Python files under the given paths.', + ) + parser.add_argument( + 'paths', + nargs='+', + help='Relative paths to scan (e.g. src tests)', + ) + return parser + + +def main(argv: Optional[list[str]] = None) -> int: + parser = build_parser() + args = parser.parse_args(argv) + + for base_dir in args.paths: + base_path = Path(base_dir) + if not base_path.exists(): + parser.error(f'Path does not exist: {base_dir}') + + remove_header_from_py_files(base_dir) + + return 0 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/tools/test_scripts.py b/tools/test_scripts.py new file mode 100644 index 00000000..2d347579 --- /dev/null +++ b/tools/test_scripts.py @@ -0,0 +1,55 @@ +"""Test runner for tutorial scripts in the 'tutorials' directory. + +This test discovers and executes all Python scripts located under the +'tutorials' directory to ensure they run without errors. + +Important: each script must be executed in a fresh Python process. +Running many tutorials in-process (e.g. via runpy) leaks global state +between scripts (notably cached calculator dictionaries keyed only by +model/experiment names), which can cause false failures. +""" + +import os +import subprocess # noqa: S404 +import sys +from pathlib import Path + +import pytest + +_repo_root = Path(__file__).resolve().parents[1] +_src_root = _repo_root / 'src' + +# Discover tutorial scripts, excluding temporary checkpoint files +TUTORIALS = [ + p for p in Path('docs/docs/tutorials').rglob('*.py') if '.ipynb_checkpoints' not in p.parts +] + + +@pytest.mark.parametrize('script_path', TUTORIALS) +def test_script_runs(script_path: Path): + """Execute a tutorial script and fail if it raises an exception. + + Each script is run in the context of __main__ to mimic standalone + execution. + """ + env = os.environ.copy() + if _src_root.exists(): + existing = env.get('PYTHONPATH', '') + env['PYTHONPATH'] = ( + str(_src_root) if not existing else str(_src_root) + os.pathsep + existing + ) + + # This is a test harness executing repo-local tutorial scripts. + # We intentionally use subprocess isolation to prevent cross-test + # global state leaks (e.g. calculator caches) that can cause false + # failures when running tutorials in a shared interpreter. + result = subprocess.run( # noqa: S603 + [sys.executable, str(script_path)], + cwd=str(_repo_root), + env=env, + capture_output=True, + text=True, + ) + if result.returncode != 0: + details = (result.stdout or '') + (result.stderr or '') + pytest.fail(f'{script_path}\n{details.strip()}') diff --git a/tools/update_docs_assets.py b/tools/update_docs_assets.py new file mode 100644 index 00000000..26c7c41b --- /dev/null +++ b/tools/update_docs_assets.py @@ -0,0 +1,91 @@ +""" +Update documentation assets from the assets-branding repository. + +This script fetches branding assets (logos, icons, images) from the +easyscience/assets-branding GitHub repository and copies them to the +appropriate locations in the documentation directory. +""" + +import shutil +from pathlib import Path + +import pooch + +# Configuration: Define what to fetch and where to copy +GITHUB_REPO = 'easyscience/assets-branding' +GITHUB_BRANCH = 'master' +BASE_URL = f'https://raw.githubusercontent.com/{GITHUB_REPO}/refs/heads/{GITHUB_BRANCH}' +PROJECT_NAME = 'easyscience' + +# Mapping of source files to destination paths +# Format: "source_path_in_repo": "destination_path_in_project" +ASSETS_MAP = { + # Logos + f'{PROJECT_NAME}/logos/dark.svg': 'docs/docs/assets/images/logo_dark.svg', + f'{PROJECT_NAME}/logos/light.svg': 'docs/docs/assets/images/logo_light.svg', + # Favicon + f'{PROJECT_NAME}/icons/color.png': 'docs/docs/assets/images/favicon.png', + # Icon overrides + f'{PROJECT_NAME}/icons/bw.svg': f'docs/overrides/.icons/{PROJECT_NAME}.svg', + 'easyscience-org/icons/eso-icon_bw.svg': 'docs/overrides/.icons/easyscience.svg', +} + + +def fetch_and_copy_asset( + source_path: str, + dest_path: str, + cache_dir: Path, +) -> None: + """ + Fetch an asset from GitHub and copy it to the destination. + + Args: + source_path: Path to the file in the GitHub repository + dest_path: Destination path in the project + cache_dir: Directory to cache downloaded files + """ + url = f'{BASE_URL}/{source_path}' + + # Create a unique cache filename based on source path + cache_filename = source_path.replace('/', '_') + + # Download file using pooch + file_path = pooch.retrieve( + url=url, + known_hash=None, # Skip hash verification + path=cache_dir, + fname=cache_filename, + ) + + # Create destination directory if it doesn't exist + dest = Path(dest_path) + dest.parent.mkdir(parents=True, exist_ok=True) + + # Copy the file to destination + shutil.copy2(file_path, dest) + print(f'Copied {file_path} -> {dest_path}') + + +def main(): + """Main function to update all documentation assets.""" + print('📥 Updating documentation assets...') + print(f' Repository: {GITHUB_REPO}') + print(f' Branch: {GITHUB_BRANCH}\n') + + # Use a temporary cache directory + cache_dir = Path.home() / '.cache' / GITHUB_REPO + cache_dir.mkdir(parents=True, exist_ok=True) + + # Fetch and copy each asset + for source_path, dest_path in ASSETS_MAP.items(): + try: + fetch_and_copy_asset(source_path, dest_path, cache_dir) + print() + except Exception as e: + print(f'❌ Failed to fetch {source_path}: {e}') + + print('\n✅ Documentation assets updated successfully!') + + +if __name__ == '__main__': + main() diff --git a/tools/update_github_labels.py b/tools/update_github_labels.py new file mode 100644 index 00000000..8ec8c2d7 --- /dev/null +++ b/tools/update_github_labels.py @@ -0,0 +1,339 @@ +"""Set/update GitHub labels for current or specified easyscience +repository. + +Requires: + - gh CLI installed + - gh auth login completed + +Usage: + python update_github_labels.py + python update_github_labels.py --dry-run + python update_github_labels.py --repo easyscience/my-repo + python update_github_labels.py --repo easyscience/my-repo --dry-run +""" + +from __future__ import annotations + +import argparse +import json +import shlex +import subprocess +import sys +from dataclasses import dataclass + +EASYSCIENCE_ORG = 'easyscience' + + +# Data structures + + +@dataclass(frozen=True) +class Label: + """A GitHub label with name, color, and description.""" + + name: str + color: str + description: str = '' + + +@dataclass(frozen=True) +class LabelRename: + """Mapping from old label name to new label name.""" + + old: str + new: str + + +class Colors: + """Hex color codes for label groups.""" + + SCOPE = 'd73a4a' + MAINTAINER = '0e8a16' + PRIORITY = 'fbca04' + BOT = '5319e7' + + +LABEL_RENAMES = [ + # Default GitHub labels to rename (if they exist) + LabelRename('bug', '[scope] bug'), + LabelRename('documentation', '[scope] documentation'), + LabelRename('duplicate', '[maintainer] duplicate'), + LabelRename('enhancement', '[scope] enhancement'), + LabelRename('good first issue', '[maintainer] good first issue'), + LabelRename('help wanted', '[maintainer] help wanted'), + LabelRename('invalid', '[maintainer] invalid'), + LabelRename('question', '[maintainer] question'), + LabelRename('wontfix', '[maintainer] wontfix'), + # Custom label renames (if they exist) + LabelRename('[bot] pull request', '[bot] release'), +] + +LABELS = [ + # Scope labels + Label( + '[scope] bug', + Colors.SCOPE, + 'Bug report or fix (major.minor.PATCH)', + ), + Label( + '[scope] documentation', + Colors.SCOPE, + 'Documentation only changes (major.minor.patch.POST)', + ), + Label( + '[scope] enhancement', + Colors.SCOPE, + 'Adds/improves features (major.MINOR.patch)', + ), + Label( + '[scope] maintenance', + Colors.SCOPE, + 'Code/tooling cleanup, no feature or bugfix (major.minor.PATCH)', + ), + Label( + '[scope] significant', + Colors.SCOPE, + 'Breaking or major changes (MAJOR.minor.patch)', + ), + Label( + '[scope] ⚠️ label needed', + Colors.SCOPE, + 'Automatically added to issues and PRs without a [scope] label', + ), + # Maintainer labels + Label( + '[maintainer] duplicate', + Colors.MAINTAINER, + 'Already reported or submitted', + ), + Label( + '[maintainer] good first issue', + Colors.MAINTAINER, + 'Good entry-level issue for newcomers', + ), + Label( + '[maintainer] help wanted', + Colors.MAINTAINER, + 'Needs additional help to resolve or implement', + ), + Label( + '[maintainer] invalid', + Colors.MAINTAINER, + 'Invalid, incorrect or outdated', + ), + Label( + '[maintainer] question', + Colors.MAINTAINER, + 'Needs clarification, discussion, or more information', + ), + Label( + '[maintainer] wontfix', + Colors.MAINTAINER, + 'Will not be fixed or continued', + ), + # Priority labels + Label( + '[priority] lowest', + Colors.PRIORITY, + 'Very low urgency', + ), + Label( + '[priority] low', + Colors.PRIORITY, + 'Low importance', + ), + Label( + '[priority] medium', + Colors.PRIORITY, + 'Normal/default priority', + ), + Label( + '[priority] high', + Colors.PRIORITY, + 'Should be prioritized soon', + ), + Label( + '[priority] highest', + Colors.PRIORITY, + 'Urgent. Needs attention ASAP', + ), + Label( + '[priority] ⚠️ label needed', + Colors.PRIORITY, + 'Automatically added to issues without a [priority] label', + ), + # Bot label + Label( + '[bot] release', + Colors.BOT, + 'Automated release PR. Excluded from changelog/versioning', + ), + Label( + '[bot] backmerge', + Colors.BOT, + 'Automated backmerge master → develop failed due to conflicts', + ), +] + + +# Helpers + + +@dataclass(frozen=True) +class CmdResult: + """Result of a shell command execution.""" + + returncode: int + stdout: str + stderr: str + + +def run_cmd( + args: list[str], + *, + dry_run: bool, + check: bool = True, +) -> CmdResult: + """Run a command (or print it in dry-run mode).""" + cmd_str = ' '.join(shlex.quote(a) for a in args) + + if dry_run: + print(f' [dry-run] {cmd_str}') + return CmdResult(0, '', '') + + proc = subprocess.run( + args=args, + text=True, + capture_output=True, + ) + result = CmdResult( + proc.returncode, + proc.stdout.strip(), + proc.stderr.strip(), + ) + + if check and proc.returncode != 0: + raise RuntimeError(f'Command failed ({proc.returncode}): {cmd_str}\n{result.stderr}') + + return result + + +def get_current_repo() -> str: + """Get the current repository name in 'owner/repo' format.""" + result = subprocess.run( + args=[ + 'gh', + 'repo', + 'view', + '--json', + 'nameWithOwner', + ], + text=True, + capture_output=True, + check=True, + ) + data = json.loads(result.stdout) + name_with_owner = data.get('nameWithOwner', '') + + if '/' not in name_with_owner: + raise RuntimeError('Could not determine current repository name') + + return name_with_owner + + +def rename_label( + repo: str, + rename: LabelRename, + *, + dry_run: bool, +) -> None: + """Rename a label, silently skipping if it doesn't exist.""" + result = run_cmd( + args=[ + 'gh', + 'label', + 'edit', + rename.old, + '--name', + rename.new, + '--repo', + repo, + ], + dry_run=dry_run, + check=False, + ) + + if dry_run or result.returncode == 0: + print(f' Rename: {rename.old!r} → {rename.new!r}') + else: + print(f' Skip (not found): {rename.old!r}') + + +def upsert_label( + repo: str, + label: Label, + *, + dry_run: bool, +) -> None: + """Create or update a label.""" + run_cmd( + [ + 'gh', + 'label', + 'create', + label.name, + '--color', + label.color, + '--description', + label.description, + '--force', + '--repo', + repo, + ], + dry_run=dry_run, + ) + print(f' Upsert: {label.name!r}') + + +# Main + + +def main() -> int: + """Entry point: parse arguments and sync labels.""" + parser = argparse.ArgumentParser(description='Sync GitHub labels for easyscience repos') + parser.add_argument( + '--repo', + help='Target repository (owner/name)', + ) + parser.add_argument( + '--dry-run', + action='store_true', + help='Print actions without applying changes', + ) + args = parser.parse_args() + + repo = args.repo or get_current_repo() + org = repo.split('/')[0] + + if org.lower() != EASYSCIENCE_ORG: + print(f"Error: repository '{repo}' is not under '{EASYSCIENCE_ORG}'", file=sys.stderr) + return 2 + + print(f'Repository: {repo}') + if args.dry_run: + print('Mode: DRY-RUN (no changes will be made)\n') + + print('\nRenaming default labels...') + for rename in LABEL_RENAMES: + rename_label(repo, rename, dry_run=args.dry_run) + + print('\nUpserting labels...') + for label in LABELS: + upsert_label(repo, label, dry_run=args.dry_run) + + print('\nDone.') + return 0 + + +if __name__ == '__main__': + raise SystemExit(main())