diff --git a/.badgery.yaml b/.badgery.yaml deleted file mode 100644 index 99bcdc1c..00000000 --- a/.badgery.yaml +++ /dev/null @@ -1,72 +0,0 @@ -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 e17376e8..5cf1eedd 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] + 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 diff --git a/.copier-answers.yml b/.copier-answers.yml index 335c340b..a3add030 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,20 +1,12 @@ -# 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 +# 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 diff --git a/.github/actions/download-artifact/action.yml b/.github/actions/download-artifact/action.yml deleted file mode 100644 index e4fd62f5..00000000 --- a/.github/actions/download-artifact/action.yml +++ /dev/null @@ -1,50 +0,0 @@ -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 deleted file mode 100644 index ab32da56..00000000 --- a/.github/actions/github-script/action.yml +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index 4b28eaf8..00000000 --- a/.github/actions/setup-easyscience-bot/action.yml +++ /dev/null @@ -1,40 +0,0 @@ -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 167ee623..8c68f51e 100644 --- a/.github/actions/setup-pixi/action.yml +++ b/.github/actions/setup-pixi/action.yml @@ -4,21 +4,13 @@ inputs: environments: description: 'Pixi environments to setup' required: false - default: 'default' + default: 'dev' activate-environment: description: 'Environment to activate' required: false - default: 'default' + default: 'dev' 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' + description: 'Whether to run install' required: false default: 'true' cache: @@ -33,12 +25,10 @@ inputs: runs: using: 'composite' steps: - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@v0.9.0 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 }} + post-cleanup: ${{ inputs.post-cleanup }} \ No newline at end of file diff --git a/.github/actions/upload-artifact/action.yml b/.github/actions/upload-artifact/action.yml deleted file mode 100644 index 825ac396..00000000 --- a/.github/actions/upload-artifact/action.yml +++ /dev/null @@ -1,49 +0,0 @@ -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 deleted file mode 100644 index 37d6298a..00000000 --- a/.github/actions/upload-codecov/action.yml +++ /dev/null @@ -1,42 +0,0 @@ -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 deleted file mode 100644 index c0d3fbee..00000000 --- a/.github/configs/pages-deployment.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "source": { - "branch": "gh-pages", - "path": "/" - } -} diff --git a/.github/configs/rulesets-develop.json b/.github/configs/rulesets-develop.json deleted file mode 100644 index 04489e52..00000000 --- a/.github/configs/rulesets-develop.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "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 deleted file mode 100644 index ebf38928..00000000 --- a/.github/configs/rulesets-gh-pages.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "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 deleted file mode 100644 index f658a5c6..00000000 --- a/.github/configs/rulesets-master.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "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 new file mode 100644 index 00000000..a95ea8fc --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,32 @@ +# 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 deleted file mode 100644 index f6bd98b5..00000000 --- a/.github/scripts/backmerge-conflict-issue.js +++ /dev/null @@ -1,69 +0,0 @@ -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 deleted file mode 100644 index 47b3384a..00000000 --- a/.github/workflows/backmerge.yml +++ /dev/null @@ -1,109 +0,0 @@ -# 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 deleted file mode 100644 index 7305679b..00000000 --- a/.github/workflows/cleanup.yml +++ /dev/null @@ -1,84 +0,0 @@ -# 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 new file mode 100644 index 00000000..bcd75a1a --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,68 @@ +# 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 deleted file mode 100644 index cd9ff1e0..00000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,94 +0,0 @@ -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 deleted file mode 100644 index 5159f71b..00000000 --- a/.github/workflows/dashboard.yml +++ /dev/null @@ -1,104 +0,0 @@ -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 deleted file mode 100644 index c23c2c8c..00000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,184 +0,0 @@ -# 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 new file mode 100644 index 00000000..958a8dde --- /dev/null +++ b/.github/workflows/documentation-build.yml @@ -0,0 +1,49 @@ +# 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 deleted file mode 100644 index 3a60cdd7..00000000 --- a/.github/workflows/issues-labels.yml +++ /dev/null @@ -1,42 +0,0 @@ -# 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 deleted file mode 100644 index fc451d14..00000000 --- a/.github/workflows/lint-format.yml +++ /dev/null @@ -1,130 +0,0 @@ -# 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 new file mode 100644 index 00000000..f35a232c --- /dev/null +++ b/.github/workflows/nightly-check.yml @@ -0,0 +1,24 @@ +# 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 new file mode 100644 index 00000000..1d4435f4 --- /dev/null +++ b/.github/workflows/ossar-analysis.yml @@ -0,0 +1,38 @@ +# 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 deleted file mode 100644 index 642cd318..00000000 --- a/.github/workflows/pr-labels.yml +++ /dev/null @@ -1,56 +0,0 @@ -# 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 deleted file mode 100644 index 95a3b394..00000000 --- a/.github/workflows/pypi-publish.yml +++ /dev/null @@ -1,46 +0,0 @@ -# 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 deleted file mode 100644 index 6f4e582f..00000000 --- a/.github/workflows/pypi-test.yml +++ /dev/null @@ -1,80 +0,0 @@ -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 new file mode 100644 index 00000000..ed16dfdd --- /dev/null +++ b/.github/workflows/python-ci.yml @@ -0,0 +1,94 @@ +# 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 new file mode 100644 index 00000000..9158390b --- /dev/null +++ b/.github/workflows/python-package.yml @@ -0,0 +1,46 @@ +# 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 new file mode 100644 index 00000000..17a81037 --- /dev/null +++ b/.github/workflows/python-publish.yml @@ -0,0 +1,38 @@ +# 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 deleted file mode 100644 index 4dd25dfa..00000000 --- a/.github/workflows/release-notes.yml +++ /dev/null @@ -1,71 +0,0 @@ -# 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 deleted file mode 100644 index 7e6fda49..00000000 --- a/.github/workflows/release-pr.yml +++ /dev/null @@ -1,55 +0,0 @@ -# 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 new file mode 100644 index 00000000..eb3f34c2 --- /dev/null +++ b/.github/workflows/release_drafter.yml @@ -0,0 +1,16 @@ +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 deleted file mode 100644 index 9b34cccf..00000000 --- a/.github/workflows/security.yml +++ /dev/null @@ -1,93 +0,0 @@ -# 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 deleted file mode 100644 index ecf6b40c..00000000 --- a/.github/workflows/test-trigger.yml +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index 05998190..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,271 +0,0 @@ -# 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 deleted file mode 100644 index 1bc27f4f..00000000 --- a/.github/workflows/tutorial-tests-trigger.yml +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index 4c9244d0..00000000 --- a/.github/workflows/tutorial-tests.yml +++ /dev/null @@ -1,64 +0,0 @@ -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 new file mode 100644 index 00000000..4315fe7e --- /dev/null +++ b/.github/workflows/verify_issue_labels.yml @@ -0,0 +1,33 @@ +# 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 new file mode 100644 index 00000000..e7eb0f5c --- /dev/null +++ b/.github/workflows/verify_pr_labels.yml @@ -0,0 +1,23 @@ +# 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 0500ede3..5d0e0e91 100644 --- a/.gitignore +++ b/.gitignore @@ -1,45 +1,52 @@ +# 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 -dist/ -build/ +build *.spec -# MkDocs -docs/site/ - -# Jupyter Notebooks +# Jupyter .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 feb102db..16fd4a4f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,61 +1,23 @@ repos: - - 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/psf/black + rev: 22.3.0 + hooks: + - id: black + exclude: ^dist/ - - 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] +- 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] diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 788ec8fa..00000000 --- a/.prettierignore +++ /dev/null @@ -1,17 +0,0 @@ -# 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 fa245c37..cb8357ab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,406 +1,134 @@ -# Contributing to EasyScience +# Contributing -Thank you for your interest in 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. -This guide explains how to: +Please note we have a code of conduct, please follow it in all your interactions with the project. -- Report issues -- Contribute code -- Improve documentation -- Suggest enhancements -- Interact with the EasyScience community +## Development Setup -Whether you are an experienced developer or contributing for the first -time, this document walks you through the entire process step by step. +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. -Please make sure you follow the EasyScience organization-wide -[Code of Conduct](https://github.com/easyscience/.github/blob/master/CODE_OF_CONDUCT.md). +### Prerequisites ---- +1. Install pixi following the [official installation guide](https://pixi.sh/latest/#installation) -## 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: +### Getting Started +1. Fork and clone the repository: ```bash -git fetch upstream -git pull upstream develop +git clone https://github.com/your-username/EasyScience.git +cd EasyScience ``` -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: - +2. Set up the development 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 ``` -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: - +3. Run tests to verify everything is working: ```bash -pixi run check +pixi run test ``` -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. +### Development Workflow ---- +- **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` -## 7. Opening a Pull Request +### Before Submitting a Pull Request -Push your branch: +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 -```bash -git push origin my-change -``` +## Pull Request Process -On GitHub: +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. -- 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 +## Code of Conduct -### Pull Request Title +### Our Pledge -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 -``` +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. -Open the URL shown in the terminal to review your changes. +### Our Standards ---- +Examples of behavior that contributes to creating a positive environment +include: -## 11. Reporting Issues +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community -If you find a bug but do not want to fix it: +Examples of unacceptable behavior by participants include: -- Search existing issues first -- Provide clear reproduction steps -- Include logs and environment details +* 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 -Clear issue reports help maintainers significantly. +### Our Responsibilities ---- +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. -## 12. Security Issues +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. -Do **not** report security vulnerabilities publicly. +### Scope -If you discover a potential vulnerability, contact the maintainers -privately. +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. ---- +### Enforcement -## 13. Releases +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. -Releases are created by merging `develop` into `master`. +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. -Once your contribution is merged into `develop`, it will be included in -the next stable release. +### Attribution ---- +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] -Thank you for contributing to EasyScience and the EasyScience ecosystem! +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/legacy/Examples/README.rst b/Examples/README.rst similarity index 100% rename from legacy/Examples/README.rst rename to Examples/README.rst diff --git a/legacy/Examples/base/README.rst b/Examples/base/README.rst similarity index 100% rename from legacy/Examples/base/README.rst rename to Examples/base/README.rst diff --git a/legacy/Examples/base/plot_baseclass1.py b/Examples/base/plot_baseclass1.py similarity index 100% rename from legacy/Examples/base/plot_baseclass1.py rename to Examples/base/plot_baseclass1.py diff --git a/legacy/Examples/fitting/README.rst b/Examples/fitting/README.rst similarity index 100% rename from legacy/Examples/fitting/README.rst rename to Examples/fitting/README.rst diff --git a/LICENSE b/LICENSE index c4e3e48e..f21bf746 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ BSD 3-Clause License -Copyright (c) 2021-2026 EasyScience contributors. +Copyright (c) 2025, Easyscience contributors (https://github.com/EasyScience) +All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/legacy/PARAMETER_DEPENDENCY_SERIALIZATION.md b/PARAMETER_DEPENDENCY_SERIALIZATION.md similarity index 73% rename from legacy/PARAMETER_DEPENDENCY_SERIALIZATION.md rename to PARAMETER_DEPENDENCY_SERIALIZATION.md index 66a6659b..82bf0383 100644 --- a/legacy/PARAMETER_DEPENDENCY_SERIALIZATION.md +++ b/PARAMETER_DEPENDENCY_SERIALIZATION.md @@ -1,31 +1,19 @@ # 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 @@ -88,7 +76,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) @@ -123,14 +111,11 @@ 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 @@ -139,31 +124,21 @@ dependent parameters: 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 @@ -177,20 +152,15 @@ 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)` @@ -198,37 +168,26 @@ resolves them. 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 @@ -242,18 +201,16 @@ 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. +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 diff --git a/README.md b/README.md index 15bf48f8..b41a80be 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,45 @@ -

- - - - - - - 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) +[![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. + + diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index f62b13ab..00000000 --- a/codecov.yml +++ /dev/null @@ -1,13 +0,0 @@ -# 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 new file mode 100644 index 00000000..1a27587e --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# 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 deleted file mode 100644 index 687749a2..00000000 --- a/docs/docs/api-reference/base_classes.md +++ /dev/null @@ -1 +0,0 @@ -::: easyscience.base_classes diff --git a/docs/docs/api-reference/fitting.md b/docs/docs/api-reference/fitting.md deleted file mode 100644 index ca21c5e6..00000000 --- a/docs/docs/api-reference/fitting.md +++ /dev/null @@ -1 +0,0 @@ -::: easyscience.fitting diff --git a/docs/docs/api-reference/global_object.md b/docs/docs/api-reference/global_object.md deleted file mode 100644 index 6e6987a8..00000000 --- a/docs/docs/api-reference/global_object.md +++ /dev/null @@ -1 +0,0 @@ -::: easyscience.global_object diff --git a/docs/docs/api-reference/index.md b/docs/docs/api-reference/index.md deleted file mode 100644 index 4bd6f561..00000000 --- a/docs/docs/api-reference/index.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -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 deleted file mode 100644 index f06a9356..00000000 --- a/docs/docs/api-reference/io.md +++ /dev/null @@ -1 +0,0 @@ -::: easyscience.io diff --git a/docs/docs/api-reference/job.md b/docs/docs/api-reference/job.md deleted file mode 100644 index c743ba62..00000000 --- a/docs/docs/api-reference/job.md +++ /dev/null @@ -1 +0,0 @@ -::: easyscience.job diff --git a/docs/docs/api-reference/models.md b/docs/docs/api-reference/models.md deleted file mode 100644 index 2471f604..00000000 --- a/docs/docs/api-reference/models.md +++ /dev/null @@ -1 +0,0 @@ -::: easyscience.models diff --git a/docs/docs/api-reference/utils.md b/docs/docs/api-reference/utils.md deleted file mode 100644 index d703ac5f..00000000 --- a/docs/docs/api-reference/utils.md +++ /dev/null @@ -1 +0,0 @@ -::: easyscience.utils diff --git a/docs/docs/api-reference/variable.md b/docs/docs/api-reference/variable.md deleted file mode 100644 index e55a4ee0..00000000 --- a/docs/docs/api-reference/variable.md +++ /dev/null @@ -1 +0,0 @@ -::: easyscience.variable diff --git a/docs/docs/assets/images/favicon.png b/docs/docs/assets/images/favicon.png deleted file mode 100644 index 1cdd9d9e..00000000 Binary files a/docs/docs/assets/images/favicon.png and /dev/null differ diff --git a/docs/docs/assets/images/logo_dark.svg b/docs/docs/assets/images/logo_dark.svg deleted file mode 100644 index 980c3174..00000000 --- a/docs/docs/assets/images/logo_dark.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - 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 deleted file mode 100644 index 89b48f9f..00000000 --- a/docs/docs/assets/images/logo_light.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - 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 deleted file mode 100644 index dd3fc356..00000000 --- a/docs/docs/assets/javascripts/extra.js +++ /dev/null @@ -1,29 +0,0 @@ -(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 deleted file mode 100644 index a92ce69a..00000000 --- a/docs/docs/assets/javascripts/mathjax.js +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index a625be80..00000000 --- a/docs/docs/assets/stylesheets/extra.css +++ /dev/null @@ -1,359 +0,0 @@ -/*************/ -/* 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 deleted file mode 100644 index 5a3e9727..00000000 --- a/docs/docs/index.md +++ /dev/null @@ -1,21 +0,0 @@ -![](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 deleted file mode 100644 index 64064d08..00000000 --- a/docs/docs/installation-and-setup/index.md +++ /dev/null @@ -1,281 +0,0 @@ ---- -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 deleted file mode 100644 index b95b6de3..00000000 --- a/docs/docs/introduction/index.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -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 deleted file mode 100644 index a4929a5c..00000000 --- a/docs/docs/tutorials/fitting-qens.ipynb +++ /dev/null @@ -1,359 +0,0 @@ -{ - "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 deleted file mode 100644 index 06b0cc36..00000000 --- a/docs/docs/tutorials/fitting-sans.ipynb +++ /dev/null @@ -1,349 +0,0 @@ -{ - "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 deleted file mode 100644 index 8728e9ed..00000000 --- a/docs/docs/tutorials/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -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 deleted file mode 100644 index bff8e315..00000000 --- a/docs/docs/user-guide/index.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -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 deleted file mode 100644 index 682f16ff..00000000 --- a/docs/includes/abbreviations.md +++ /dev/null @@ -1,15 +0,0 @@ - - -*[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 new file mode 100644 index 00000000..135acda3 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@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 deleted file mode 100644 index c721c75d..00000000 --- a/docs/mkdocs.yml +++ /dev/null @@ -1,189 +0,0 @@ -# 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 deleted file mode 100644 index b4fdd4f3..00000000 --- a/docs/overrides/.icons/app.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/docs/overrides/.icons/easyscience.svg b/docs/overrides/.icons/easyscience.svg deleted file mode 100644 index fb514912..00000000 --- a/docs/overrides/.icons/easyscience.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/overrides/.icons/google-colab.svg b/docs/overrides/.icons/google-colab.svg deleted file mode 100644 index 9cd9d1b0..00000000 --- a/docs/overrides/.icons/google-colab.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/docs/overrides/main.html b/docs/overrides/main.html deleted file mode 100644 index 2e146827..00000000 --- a/docs/overrides/main.html +++ /dev/null @@ -1,39 +0,0 @@ -{% 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 deleted file mode 100644 index 78fa69ca..00000000 --- a/docs/overrides/partials/logo.html +++ /dev/null @@ -1,15 +0,0 @@ -{% 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 new file mode 100644 index 00000000..77c1f9a4 Binary files /dev/null and b/docs/src/_static/ec_logo_single.png differ diff --git a/docs/src/_static/ec_sidebar.png b/docs/src/_static/ec_sidebar.png new file mode 100644 index 00000000..a8bb6c7b Binary files /dev/null and b/docs/src/_static/ec_sidebar.png differ diff --git a/docs/src/_static/ec_sidebar_w.png b/docs/src/_static/ec_sidebar_w.png new file mode 100644 index 00000000..d1f407a3 Binary files /dev/null and b/docs/src/_static/ec_sidebar_w.png differ diff --git a/docs/src/_static/favicon.ico b/docs/src/_static/favicon.ico new file mode 100644 index 00000000..9281805b Binary files /dev/null and b/docs/src/_static/favicon.ico differ diff --git a/docs/src/conf.py b/docs/src/conf.py new file mode 100644 index 00000000..f8445631 --- /dev/null +++ b/docs/src/conf.py @@ -0,0 +1,228 @@ +#!/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 new file mode 100644 index 00000000..0a694090 --- /dev/null +++ b/docs/src/fitting/introduction.rst @@ -0,0 +1,362 @@ +====================== +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 new file mode 100644 index 00000000..4d0cef44 --- /dev/null +++ b/docs/src/getting-started/installation.rst @@ -0,0 +1,33 @@ +************ +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 new file mode 100644 index 00000000..d5516a1c --- /dev/null +++ b/docs/src/getting-started/overview.rst @@ -0,0 +1,224 @@ +.. _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 new file mode 100644 index 00000000..10f795a8 --- /dev/null +++ b/docs/src/index.rst @@ -0,0 +1,181 @@ +======================================= +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 new file mode 100644 index 00000000..1d91803c --- /dev/null +++ b/docs/src/reference/base.rst @@ -0,0 +1,323 @@ +============== +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/legacy/examples_old/dataset_examples.ipynb b/examples_old/dataset_examples.ipynb similarity index 100% rename from legacy/examples_old/dataset_examples.ipynb rename to examples_old/dataset_examples.ipynb diff --git a/legacy/examples_old/dimer_example.ipynb b/examples_old/dimer_example.ipynb similarity index 100% rename from legacy/examples_old/dimer_example.ipynb rename to examples_old/dimer_example.ipynb diff --git a/legacy/examples_old/example1.py b/examples_old/example1.py similarity index 100% rename from legacy/examples_old/example1.py rename to examples_old/example1.py diff --git a/legacy/examples_old/example1_dream.py b/examples_old/example1_dream.py similarity index 100% rename from legacy/examples_old/example1_dream.py rename to examples_old/example1_dream.py diff --git a/legacy/examples_old/example2.py b/examples_old/example2.py similarity index 100% rename from legacy/examples_old/example2.py rename to examples_old/example2.py diff --git a/legacy/examples_old/example3.py b/examples_old/example3.py similarity index 100% rename from legacy/examples_old/example3.py rename to examples_old/example3.py diff --git a/legacy/examples_old/example4.py b/examples_old/example4.py similarity index 100% rename from legacy/examples_old/example4.py rename to examples_old/example4.py diff --git a/legacy/examples_old/example5_broken.py b/examples_old/example5_broken.py similarity index 100% rename from legacy/examples_old/example5_broken.py rename to examples_old/example5_broken.py diff --git a/legacy/examples_old/example6_broken.py b/examples_old/example6_broken.py similarity index 100% rename from legacy/examples_old/example6_broken.py rename to examples_old/example6_broken.py diff --git a/legacy/examples_old/example_dataset.py b/examples_old/example_dataset.py similarity index 100% rename from legacy/examples_old/example_dataset.py rename to examples_old/example_dataset.py diff --git a/legacy/examples_old/example_dataset2.py b/examples_old/example_dataset2.py similarity index 100% rename from legacy/examples_old/example_dataset2.py rename to examples_old/example_dataset2.py diff --git a/legacy/examples_old/example_dataset2pt2.py b/examples_old/example_dataset2pt2.py similarity index 100% rename from legacy/examples_old/example_dataset2pt2.py rename to examples_old/example_dataset2pt2.py diff --git a/legacy/examples_old/example_dataset2pt2_broken.py b/examples_old/example_dataset2pt2_broken.py similarity index 100% rename from legacy/examples_old/example_dataset2pt2_broken.py rename to examples_old/example_dataset2pt2_broken.py diff --git a/legacy/examples_old/example_dataset3.py b/examples_old/example_dataset3.py similarity index 100% rename from legacy/examples_old/example_dataset3.py rename to examples_old/example_dataset3.py diff --git a/legacy/examples_old/example_dataset3pt2.py b/examples_old/example_dataset3pt2.py similarity index 100% rename from legacy/examples_old/example_dataset3pt2.py rename to examples_old/example_dataset3pt2.py diff --git a/legacy/examples_old/example_dataset4.py b/examples_old/example_dataset4.py similarity index 100% rename from legacy/examples_old/example_dataset4.py rename to examples_old/example_dataset4.py diff --git a/legacy/examples_old/example_dataset4_2.py b/examples_old/example_dataset4_2.py similarity index 100% rename from legacy/examples_old/example_dataset4_2.py rename to examples_old/example_dataset4_2.py diff --git a/pixi.lock b/pixi.lock index 5d5f40a6..00863b1e 100644 --- a/pixi.lock +++ b/pixi.lock @@ -5,3068 +5,1159 @@ 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/_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/_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/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/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.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 + - 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/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/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/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/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/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/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-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/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-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/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/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/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/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-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/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/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.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/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/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/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/b0/d0/89247ec250369fc76db477720a26b2fce7ba079ff1380e4ab4529d2fe233/debugpy-1.8.17-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/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/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/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/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/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/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/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/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.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/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/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/85/e2/05328bd2621be49a6fed9e3030b1e51a2d04537d3f816d211b9cc53c5262/json5-0.12.1-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/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-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/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-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/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/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/22/ff/6425bf5c20d79aa5b959d1ce9e65f599632345391381c9a104133fe0b171/matplotlib-3.10.7-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/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/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/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/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/42/0f/c76bf3dba22c73c38e9b1113b017cf163f7696f50e003404ec5ecdb1e8a6/nh3-0.3.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.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/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/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/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/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/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/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/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.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/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/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/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/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/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/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/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-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/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-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/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/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/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-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/af/63/ac52b32b33ae62f2076ed5c4f6b00e065e3ccbb2063e9a2e813b2bfc95bf/restructuredtext_lint-2.0.2-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/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/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/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/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/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.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/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/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/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-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/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/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/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/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: 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_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/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/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/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.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 + - 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 - 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/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/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/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/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/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-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/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-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/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/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/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/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-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/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/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.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/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/b8/14/771700b4048774e48d2c54ed0c674273702713c9ee7acdfede40c2666747/coverage-7.12.0-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/b0/d0/89247ec250369fc76db477720a26b2fce7ba079ff1380e4ab4529d2fe233/debugpy-1.8.17-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/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/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/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/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/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/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/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/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.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/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/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/85/e2/05328bd2621be49a6fed9e3030b1e51a2d04537d3f816d211b9cc53c5262/json5-0.12.1-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/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-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/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-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/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/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/02/9c/207547916a02c78f6bdd83448d9b21afbc42f6379ed887ecf610984f3b4e/matplotlib-3.10.7-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/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/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/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/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/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/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/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/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/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/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/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/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/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.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/ef/94/46b9154a800253e7ecff5aaacdf8ebf43db99de4a2dfa18575b02548654e/psutil-7.1.3-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/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/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/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/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/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-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/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-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/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/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/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-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/af/63/ac52b32b33ae62f2076ed5c4f6b00e065e3ccbb2063e9a2e813b2bfc95bf/restructuredtext_lint-2.0.2-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/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/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/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/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/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.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/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/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/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-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/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/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/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/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: 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_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/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/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/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.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 + - 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 - 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/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/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/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/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/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-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/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-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/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/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/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/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-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/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/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.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/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/17/a7/3aa4144d3bcb719bf67b22d2d51c2d577bf801498c13cb08f64173e80497/coverage-7.12.0-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/b0/d0/89247ec250369fc76db477720a26b2fce7ba079ff1380e4ab4529d2fe233/debugpy-1.8.17-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/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/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/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/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/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/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/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/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.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/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/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/85/e2/05328bd2621be49a6fed9e3030b1e51a2d04537d3f816d211b9cc53c5262/json5-0.12.1-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/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-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/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-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/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/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/bc/d0/b3d3338d467d3fc937f0bb7f256711395cae6f78e22cef0656159950adf0/matplotlib-3.10.7-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/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/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/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/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/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/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/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/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/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/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/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/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/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.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/68/3a/9f93cff5c025029a36d9a92fef47220ab4692ee7f2be0fba9f92813d0cb8/psutil-7.1.3-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/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/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/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/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/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-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/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-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/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/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/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-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/af/63/ac52b32b33ae62f2076ed5c4f6b00e065e3ccbb2063e9a2e813b2bfc95bf/restructuredtext_lint-2.0.2-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/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/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/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/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/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.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/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/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/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-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/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/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/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/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: 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_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/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/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/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-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/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-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 + - 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 - 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/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/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/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/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/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-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/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-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/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/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/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/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-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/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/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.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/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/91/77/dd4aff9af16ff776bf355a24d87eeb48fc6acde54c907cc1ea89b14a8804/coverage-7.12.0-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/46/11/18c79a1cee5ff539a94ec4aa290c1c069a5580fd5cfd2fb2e282f8e905da/debugpy-1.8.17-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/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/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/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/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/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/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/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/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.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/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/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/85/e2/05328bd2621be49a6fed9e3030b1e51a2d04537d3f816d211b9cc53c5262/json5-0.12.1-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/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-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/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-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/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/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/e1/b6/23064a96308b9aeceeffa65e96bcde459a2ea4934d311dee20afde7407a0/matplotlib-3.10.7-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/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/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/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/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/64/9a/1a1c154f10a575d20dd634e5697805e589bbdb7673a0ad00e8da90044ba7/nh3-0.3.2-cp38-abi3-win_amd64.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/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/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/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/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/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.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/55/4c/c3ed1a622b6ae2fd3c945a366e64eb35247a31e4db16cf5095e269e8eb3c/psutil-7.1.3-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/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/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/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/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/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-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/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-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/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/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: ./ - 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/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-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/af/63/ac52b32b33ae62f2076ed5c4f6b00e065e3ccbb2063e9a2e813b2bfc95bf/restructuredtext_lint-2.0.2-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/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/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/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/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/f4/40/8561ce06dc46fd17242c7724ab25b257a2ac1b35f4ebf551b40ce6105cfa/stevedore-5.6.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/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/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/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-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/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/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/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/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: https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.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 +- 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: - - __glibc >=2.17,<3.0.a0 + - _libgcc_mutex 0.1 conda_forge - libgomp >=7.5.0 constrains: - - openmp_impl <0.0a0 + - openmp_impl 9999 license: BSD-3-Clause license_family: BSD purls: [] - size: 28948 - timestamp: 1770939786096 + 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/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 +- pypi: https://files.pythonhosted.org/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl name: aiohttp - version: 3.13.3 - sha256: f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 + version: 3.13.2 + sha256: a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a requires_dist: - aiohappyeyeballs>=2.5.0 - aiosignal>=1.4.0 @@ -3077,14 +1168,14 @@ packages: - 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' + - 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/82/71/d5c31390d18d4f58115037c432b7e0348c60f6f53b727cad33172144a112/aiohttp-3.13.3-cp311-cp311-macosx_10_9_x86_64.whl +- 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.3 - sha256: 1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 + version: 3.13.2 + sha256: 5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293 requires_dist: - aiohappyeyeballs>=2.5.0 - aiosignal>=1.4.0 @@ -3095,14 +1186,14 @@ packages: - 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' + - 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/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/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl name: aiohttp - version: 3.13.3 - sha256: 9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 + version: 3.13.2 + sha256: 088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742 requires_dist: - aiohappyeyeballs>=2.5.0 - aiosignal>=1.4.0 @@ -3113,14 +1204,14 @@ packages: - 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' + - 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/dc/f2/27cdf04c9851712d6c1b99df6821a6623c3c9e55956d4b1e318c337b5a48/aiohttp-3.13.3-cp311-cp311-win_amd64.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 name: aiohttp - version: 3.13.3 - sha256: 642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f + version: 3.13.2 + sha256: ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e requires_dist: - aiohappyeyeballs>=2.5.0 - aiosignal>=1.4.0 @@ -3131,8 +1222,8 @@ packages: - 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' + - 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 @@ -3143,23 +1234,21 @@ packages: - 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 +- 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.12.1 - sha256: d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c + 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.32.0 ; python_full_version >= '3.10' and extra == 'trio' - - trio>=0.31.0 ; python_full_version < '3.10' and extra == 'trio' + - 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 @@ -3226,10 +1315,10 @@ packages: - pytz==2025.2 ; extra == 'test' - simplejson==3.* ; extra == 'test' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/99/31/6cf181011dc738c33bf6ba7aea2e8e1d3c1f71b7dab1942f3054f66f6202/asteval-1.0.8-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/b7/da/875925db2ed80dc7b919b2817da555848b608620be9662c5f835670d5d8d/asteval-1.0.7-py3-none-any.whl name: asteval - version: 1.0.8 - sha256: 6c64385c6ff859a474953c124987c7ee8354d781c76509b2c598741c4d1d28e9 + version: 1.0.7 + sha256: d78df08681dfff59031ca624ba7030f9dc576a7a16e2f7a5137c6e7ef3ee60c4 requires_dist: - build ; extra == 'dev' - twine ; extra == 'dev' @@ -3250,30 +1339,22 @@ packages: - pytest-cov ; extra == 'test' - pytest-xdist ; extra == 'test' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/13/5c/af990f019b8dd11c5492a6371fe74a5b0276357370030b67254a87329944/async_lru-2.2.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-py3-none-any.whl name: async-lru - version: 2.2.0 - sha256: e2c1cf731eba202b59c5feedaef14ffd9d02ad0037fcda64938699f2c380eafe + version: 2.0.5 + sha256: ab95404d8d2605310d345932697371a5f40def0487c03d6d0ad9138de52c9943 requires_dist: - typing-extensions>=4.0.0 ; python_full_version < '3.11' - requires_python: '>=3.10' + requires_python: '>=3.9' - 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/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 +- pypi: https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl name: babel - version: 2.18.0 - sha256: e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 + version: 2.17.0 + sha256: 4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 requires_dist: - pytz>=2015.7 ; python_full_version < '3.9' - tzdata ; sys_platform == 'win32' and extra == 'dev' @@ -3285,26 +1366,12 @@ packages: - pytz ; extra == 'dev' - setuptools ; extra == 'dev' requires_python: '>=3.8' -- 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 +- pypi: https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl name: beautifulsoup4 - version: 4.14.3 - sha256: 0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb + version: 4.14.2 + sha256: 5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515 requires_dist: - - soupsieve>=1.6.1 + - soupsieve>1.2 - typing-extensions>=4.0.0 - cchardet ; extra == 'cchardet' - chardet ; extra == 'chardet' @@ -3330,12 +1397,12 @@ packages: version: 1.9.0 sha256: ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/cb/8c/2b30c12155ad8de0cf641d76a8b396a16d2c36bc6d50b621a62b7c4567c1/build-1.3.0-py3-none-any.whl name: build - version: 1.4.0 - sha256: 6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596 + version: 1.3.0 + sha256: 7145f0b5061ba90a1500d60bd1b13ca0a8a4cebdd0cc16ed8adf1c0e739f43b4 requires_dist: - - packaging>=24.0 + - packaging>=19.1 - pyproject-hooks - colorama ; os_name == 'nt' - importlib-metadata>=4.6 ; python_full_version < '3.10.2' @@ -3373,40 +1440,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_9.conda - sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 - md5: d2ffd7602c02f2b316fd921d39876885 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + sha256: c30daba32ddebbb7ded490f0e371eae90f51e72db620554089103b4a6934b0d5 + md5: 51a19bba1b8ebfb60df25cde030b7ebc depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 260182 - timestamp: 1771350215188 -- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda - sha256: 9f242f13537ef1ce195f93f0cc162965d6cc79da578568d6d8e50f70dd025c42 - md5: 4173ac3b19ec0a4f400b4f782910368b + size: 260341 + timestamp: 1757437258798 +- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda + sha256: 8f50b58efb29c710f3cecf2027a8d7325ba769ab10c746eff75cea3ac050b10c + md5: 97c4b3bd8a90722104798175a1bdddbf depends: - __osx >=10.13 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 133427 - timestamp: 1771350680709 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - sha256: 540fe54be35fac0c17feefbdc3e29725cce05d7367ffedfaaa1bdda234b019df - md5: 620b85a3f45526a8bc4d23fd78fc22f0 + size: 132607 + timestamp: 1757437730085 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda + sha256: b456200636bd5fecb2bec63f7e0985ad2097cf1b83d60ce0b6968dffa6d02aa1 + md5: 58fd217444c2a5701a44244faf518206 depends: - __osx >=11.0 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 124834 - timestamp: 1771350416561 -- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda - sha256: 76dfb71df5e8d1c4eded2dbb5ba15bb8fb2e2b0fe42d94145d5eed4c75c35902 - md5: 4cb8e6b48f67de0b018719cdf1136306 + size: 125061 + timestamp: 1757437486465 +- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda + sha256: d882712855624641f48aa9dc3f5feea2ed6b4e6004585d3616386a18186fe692 + md5: 1077e9333c41ff0be8edd1a5ec0ddace depends: - ucrt >=10.0.20348.0 - vc >=14.3,<15 @@ -3414,69 +1481,36 @@ packages: license: bzip2-1.0.6 license_family: BSD purls: [] - 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 + size: 55977 + timestamp: 1757437738856 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-h4c7d964_0.conda + sha256: 686a13bd2d4024fc99a22c1e0e68a7356af3ed3304a8d3ff6bb56249ad4e82f0 + md5: f98fb7db808b94bc1ec5b0e62f9f1069 depends: - __win license: ISC purls: [] - size: 147734 - timestamp: 1772006322223 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda - sha256: 67cc7101b36421c5913a1687ef1b99f85b5d6868da3abbf6ec1a4181e79782fc - md5: 4492fd26db29495f0ba23f146cd5638d + size: 152827 + timestamp: 1762967310929 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda + sha256: b986ba796d42c9d3265602bc038f6f5264095702dd546c14bc684e60c385e773 + md5: f0991f0f84902f6b6009b4d2350a83aa depends: - __unix license: ISC purls: [] - size: 147413 - timestamp: 1772006283803 -- pypi: https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl + 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 name: certifi - version: 2026.2.25 - sha256: 027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa + version: 2025.11.12 + sha256: 97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b 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 @@ -3498,13 +1532,6 @@ 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 @@ -3512,74 +1539,10 @@ packages: requires_dist: - pycparser ; implementation_name != 'PyPy' requires_python: '>=3.9' -- 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: 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 +- pypi: https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.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 + version: 5.2.0 + sha256: e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970 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 @@ -3591,28 +1554,24 @@ 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' + requires_python: '>=3.7' - 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 @@ -3625,31 +1584,6 @@ 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 @@ -3700,31 +1634,6 @@ packages: - 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 @@ -3750,31 +1659,6 @@ packages: - pytest-xdist ; extra == 'test-no-images' - wurlitzer ; extra == 'test-no-images' requires_python: '>=3.11' -- 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: 709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1 - 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/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl name: contourpy version: 1.3.3 @@ -3800,104 +1684,31 @@ packages: - pytest-xdist ; extra == 'test-no-images' - wurlitzer ; extra == 'test-no-images' requires_python: '>=3.11' -- 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: 3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42 - 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/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 +- pypi: https://files.pythonhosted.org/packages/17/a7/3aa4144d3bcb719bf67b22d2d51c2d577bf801498c13cb08f64173e80497/coverage-7.12.0-cp313-cp313-macosx_11_0_arm64.whl name: coverage - version: 7.13.4 - sha256: b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9 + version: 7.12.0 + sha256: ccf3b2ede91decd2fb53ec73c1f949c3e034129d1e0b07798ff1d02ea0c8fa4a requires_dist: - tomli ; python_full_version <= '3.11' and extra == 'toml' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/e2/0c/dbfafbe90a185943dcfbc766fe0e1909f658811492d79b741523a414a6cc/coverage-7.13.4-cp313-cp313-win_amd64.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 name: coverage - version: 7.13.4 - sha256: e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd + version: 7.12.0 + sha256: bc13baf85cd8a4cfcf4a35c7bc9d795837ad809775f782f697bf630b7e200211 requires_dist: - tomli ; python_full_version <= '3.11' and extra == 'toml' requires_python: '>=3.10' -- 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/91/77/dd4aff9af16ff776bf355a24d87eeb48fc6acde54c907cc1ea89b14a8804/coverage-7.12.0-cp313-cp313-win_amd64.whl name: coverage - version: 7.13.4 - sha256: b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b + version: 7.12.0 + sha256: ce61969812d6a98a981d147d9ac583a36ac7db7766f2e64a9d4d059c2fe29d07 requires_dist: - tomli ; python_full_version <= '3.11' and extra == 'toml' requires_python: '>=3.10' -- 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/b8/14/771700b4048774e48d2c54ed0c674273702713c9ee7acdfede40c2666747/coverage-7.12.0-cp313-cp313-macosx_10_13_x86_64.whl name: coverage - version: 7.13.4 - sha256: 19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11 + version: 7.12.0 + sha256: 47324fffca8d8eae7e185b5bb20c14645f23350f870c1649003618ea91a78941 requires_dist: - tomli ; python_full_version <= '3.11' and extra == 'toml' requires_python: '>=3.10' @@ -3914,20 +1725,15 @@ packages: - pytest-cov ; extra == 'tests' - pytest-xdist ; extra == 'tests' requires_python: '>=3.8' -- 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 +- pypi: https://files.pythonhosted.org/packages/46/11/18c79a1cee5ff539a94ec4aa290c1c069a5580fd5cfd2fb2e282f8e905da/debugpy-1.8.17-cp313-cp313-win_amd64.whl name: debugpy - version: 1.8.20 - sha256: 1f7650546e0eded1902d0f6af28f787fa1f1dbdbc97ddabaf1cd963a405930cb + version: 1.8.17 + sha256: 6c5cd6f009ad4fca8e33e5238210dc1e5f42db07d4b6ab21ac7ffa904a196420 requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/b0/d0/89247ec250369fc76db477720a26b2fce7ba079ff1380e4ab4529d2fe233/debugpy-1.8.17-py2.py3-none-any.whl name: debugpy - version: 1.8.20 - sha256: 5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7 + version: 1.8.17 + sha256: 60c7dca6571efe660ccb7a9508d73ca14b8796c4ed484c2002abba714226cfef requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl name: decorator @@ -3939,10 +1745,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/13/40/e412e277c43983693456d7f11f2bc72ca9209aa1342255bb446496d2fb48/dfo_ls-1.6.2-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/68/49/869b49db0bad6fba7c7471d612c356e745929d14e0de63acbc53e88f2a50/dfo_ls-1.6-py3-none-any.whl name: dfo-ls - version: 1.6.2 - sha256: 961d15e7194f3868e9e48da45010cb6d24d85491007fbee4e38a9f3ab8050cef + version: '1.6' + sha256: 416edce5537237fa417bd27aef5ba91201e856f3daae52ffd44cfacb10f5b771 requires_dist: - setuptools - numpy @@ -3953,95 +1759,71 @@ packages: - sphinx-rtd-theme ; extra == 'dev' - trustregion>=1.1 ; extra == 'trustregion' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl name: dill - version: 0.4.1 - sha256: 1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d + version: 0.4.0 + sha256: 44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049 requires_dist: - objgraph>=1.7.2 ; extra == 'graph' - gprof2dot>=2022.7.29 ; extra == 'profile' - requires_python: '>=3.9' + requires_python: '>=3.8' - 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/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: 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: ./ name: easyscience - version: 1.0.1+dev84 - sha256: e259614d3fa62f79e61c5da4d77be6a3479b428b17b850090289b8f306b1856c + version: 2.0.0 + sha256: 3e1433dc7b46ccbb4a5d63a22de63b3113897cd66b602a368db0c08b09b3659c requires_dist: - asteval - bumps - dfo-ls - - ipykernel - - ipympl - - ipython - - ipywidgets - - jupyterlab - lmfit - - matplotlib - numpy - - pixi-kernel - - pooch - - scipp<26.1.0 + - scipp - uncertainties + - build ; extra == 'build' + - hatchling<=1.21.0 ; extra == 'build' + - setuptools-git-versioning ; extra == 'build' - build ; 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' + - codecov ; extra == 'dev' + - flake8 ; extra == 'dev' + - jupyterlab ; extra == 'dev' + - matplotlib ; extra == 'dev' - pytest ; extra == 'dev' - pytest-cov ; extra == 'dev' - - pytest-xdist ; extra == 'dev' - - pyyaml ; extra == 'dev' - - radon ; extra == 'dev' - ruff ; extra == 'dev' - - spdx-headers ; extra == 'dev' - - validate-pyproject[all] ; extra == 'dev' - - versioningit ; 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' requires_python: '>=3.11' -- 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' + 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/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl name: executing version: 2.2.1 @@ -4068,157 +1850,30 @@ packages: - pytest-benchmark ; extra == 'devel' - pytest-cache ; extra == 'devel' - validictory ; extra == 'devel' -- pypi: https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl name: filelock - version: 3.25.0 - sha256: 5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 - requires_python: '>=3.10' -- 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: - - 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.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>=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/4b/cf/00ba28b0990982530addb8dc3e9e6f2fa9cb5c20df2abdda7baa755e8fe1/fonttools-4.61.1-cp313-cp313-macosx_10_13_universal2.whl - name: fonttools - 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>=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' + version: 3.20.0 + sha256: 339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2 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.61.1 - sha256: dc492779501fa723b04d0ab1f5be046797fee17d27700476edc7ee9ae535a61e +- 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 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/69/12/bf9f4eaa2fad039356cc627587e30ed008c03f1cebd3034376b5ee8d1d44/fonttools-4.61.1-cp311-cp311-macosx_10_9_universal2.whl + - 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 name: fonttools - version: 4.61.1 - sha256: c6604b735bb12fef8e0efd5578c9fb5d3d8532d5001ea13a19cddf295673ee09 + version: 4.60.1 + sha256: b33a7884fabd72bdf5f910d0cf46be50dce86a0362a65cfc746a4168c67eb96c 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' + - unicodedata2>=15.1.0 ; python_full_version < '3.13' 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' @@ -4227,12 +1882,12 @@ packages: - sympy ; extra == 'symfont' - xattr ; sys_platform == 'darwin' and extra == 'type1' - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.45.0 ; extra == 'repacker' + - uharfbuzz>=0.23.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' + - unicodedata2>=15.1.0 ; python_full_version < '3.13' 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' @@ -4241,18 +1896,18 @@ packages: - 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/79/61/1ca198af22f7dd22c17ab86e9024ed3c06299cfdb08170640e9996d501a0/fonttools-4.61.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - 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 name: fonttools - version: 4.61.1 - sha256: 75c1a6dfac6abd407634420c93864a1e274ebc1c7531346d9254c0d8f6ca00f9 + version: 4.60.1 + sha256: a3db56f153bd4c5c2b619ab02c5db5192e222150ce5a1bc10f16164714bc39ac 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' + - unicodedata2>=15.1.0 ; python_full_version < '3.13' 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' @@ -4261,12 +1916,12 @@ packages: - sympy ; extra == 'symfont' - xattr ; sys_platform == 'darwin' and extra == 'type1' - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.45.0 ; extra == 'repacker' + - uharfbuzz>=0.23.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' + - unicodedata2>=15.1.0 ; python_full_version < '3.13' 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' @@ -4275,18 +1930,18 @@ packages: - 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 + - 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 name: fonttools - version: 4.61.1 - sha256: 64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5 + version: 4.60.1 + sha256: 6f68576bb4bbf6060c7ab047b1574a1ebe5c50a17de62830079967b211059ebb 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' + - unicodedata2>=15.1.0 ; python_full_version < '3.13' 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' @@ -4295,12 +1950,12 @@ packages: - sympy ; extra == 'symfont' - xattr ; sys_platform == 'darwin' and extra == 'type1' - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.45.0 ; extra == 'repacker' + - uharfbuzz>=0.23.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' + - unicodedata2>=15.1.0 ; python_full_version < '3.13' 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' @@ -4309,18 +1964,18 @@ packages: - 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 + - 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 name: fonttools - version: 4.61.1 - sha256: 5ce02f38a754f207f2f06557523cd39a06438ba3aafc0639c477ac409fc64e37 + version: 4.60.1 + sha256: eedacb5c5d22b7097482fa834bda0dafa3d914a4e829ec83cdea2a01f8c813c4 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' + - unicodedata2>=15.1.0 ; python_full_version < '3.13' 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' @@ -4329,12 +1984,12 @@ packages: - sympy ; extra == 'symfont' - xattr ; sys_platform == 'darwin' and extra == 'type1' - skia-pathops>=0.5.0 ; extra == 'pathops' - - uharfbuzz>=0.45.0 ; extra == 'repacker' + - uharfbuzz>=0.23.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' + - unicodedata2>=15.1.0 ; python_full_version < '3.13' 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' @@ -4343,8 +1998,8 @@ packages: - 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' + - uharfbuzz>=0.23.0 ; extra == 'all' + requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl name: fqdn version: 1.5.1 @@ -4352,31 +2007,16 @@ 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 @@ -4387,75 +2027,11 @@ 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 @@ -4463,13 +2039,6 @@ 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 @@ -4477,20 +2046,6 @@ 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 @@ -4505,6 +2060,18 @@ 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 @@ -4535,45 +2102,28 @@ 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-78.2-h33c6efd_0.conda - sha256: 142a722072fa96cf16ff98eaaf641f54ab84744af81754c292cb81e0881c0329 - md5: 186a18e3ba246eccfc7cff00cd19a870 +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda + sha256: 71e750d509f5fa3421087ba88ef9a7b9be11c53174af3aa4d06aff4c18b38e8e + md5: 8b189310083baabfb622af68fd9d3ae3 depends: - __glibc >=2.17,<3.0.a0 - - 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 + - libgcc-ng >=12 + - libstdcxx-ng >=12 license: MIT license_family: MIT purls: [] - size: 12263724 - timestamp: 1767970604977 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda - sha256: 24bc62335106c30fecbcc1dba62c5eba06d18b90ea1061abd111af7b9c89c2d7 - md5: 114e6bfe7c5ad2525eb3597acdbf2300 + size: 12129203 + timestamp: 1720853576813 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda + sha256: 9ba12c93406f3df5ab0a43db8a4b4ef67a5871dfd401010fbe29b218b2cbe620 + md5: 5eb22c1d7b3fc4abb50d92d621583137 depends: - __osx >=11.0 license: MIT license_family: MIT purls: [] - 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' + size: 11857802 + timestamp: 1720853997952 - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl name: idna version: '3.11' @@ -4584,90 +2134,20 @@ packages: - 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/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.*' - 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/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 +- pypi: https://files.pythonhosted.org/packages/a3/17/20c2552266728ceba271967b87919664ecc0e33efca29c3efc6baf88c5f9/ipykernel-7.1.0-py3-none-any.whl name: ipykernel - version: 6.31.0 - sha256: abe5386f6ced727a70e0eb0cf1da801fa7c5fa6ff82147747d5a0406cd8c94af + version: 7.1.0 + sha256: 763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c requires_dist: - appnope>=0.1.2 ; sys_platform == 'darwin' - comm>=0.1.1 @@ -4689,8 +2169,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' @@ -4703,32 +2183,11 @@ packages: - pytest-cov ; extra == 'test' - pytest-timeout ; extra == 'test' - pytest>=7.0,<9 ; extra == 'test' - 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 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/05/aa/62893d6a591d337aa59dcc4c6f6c842f1fe20cd72c8c5c1f980255243252/ipython-9.7.0-py3-none-any.whl name: ipython - version: 9.10.0 - sha256: c6ab68cc23bba8c7e18e9b932797014cc61ea7fd6f19de180ab9ba73e65ee58d + version: 9.7.0 + sha256: bce8ac85eb9521adc94e1845b4c03d88365fd6ac2f4908ec4ed1eb1b0a065f9f requires_dist: - colorama>=0.4.4 ; sys_platform == 'win32' - decorator>=4.3.2 @@ -4768,8 +2227,7 @@ packages: - pandas>2.1 ; extra == 'test-extra' - trio>=0.1.0 ; extra == 'test-extra' - matplotlib>3.9 ; extra == 'matplotlib' - - ipython[doc,matplotlib,terminal,test,test-extra] ; extra == 'all' - - argcomplete>=3.0 ; extra == 'all' + - ipython[doc,matplotlib,test,test-extra] ; 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 @@ -4778,22 +2236,6 @@ 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 @@ -4849,34 +2291,37 @@ packages: - markupsafe>=2.0 - babel>=2.7 ; extra == 'i18n' requires_python: '>=3.7' -- 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 +- pypi: https://files.pythonhosted.org/packages/85/e2/05328bd2621be49a6fed9e3030b1e51a2d04537d3f816d211b9cc53c5262/json5-0.12.1-py3-none-any.whl name: json5 - version: 0.13.0 - sha256: 9a08e1dd65f6a4d4c6fa82d216cf2477349ec2346a38fd70cc11d2557499fbcc + 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' 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/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl name: jsonschema - version: 4.26.0 - sha256: d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce + version: 4.25.1 + sha256: 3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63 requires_dist: - attrs>=22.2.0 - jsonschema-specifications>=2023.3.6 - referencing>=0.28.4 - - rpds-py>=0.25.0 + - rpds-py>=0.7.1 - fqdn ; extra == 'format' - idna ; extra == 'format' - isoduration ; extra == 'format' @@ -4894,7 +2339,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.10' + requires_python: '>=3.9' - 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 @@ -4902,15 +2347,16 @@ packages: requires_dist: - referencing>=0.31.0 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl name: jupyter-client - version: 8.8.0 - sha256: f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a + version: 8.6.3 + sha256: e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f requires_dist: - - jupyter-core>=5.1 + - importlib-metadata>=4.8.3 ; python_full_version < '3.10' + - jupyter-core>=4.12,!=5.0.* - python-dateutil>=2.8.2 - - pyzmq>=25.0 - - tornado>=6.4.1 + - pyzmq>=23.0 + - tornado>=6.2 - traitlets>=5.3 - ipykernel ; extra == 'docs' - myst-parser ; extra == 'docs' @@ -4919,19 +2365,16 @@ 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' - - msgpack ; extra == 'test' - - mypy ; platform_python_implementation != 'PyPy' and extra == 'test' + - mypy ; extra == 'test' - paramiko ; sys_platform == 'win32' and extra == 'test' - pre-commit ; extra == 'test' - - pytest ; extra == 'test' - pytest-cov ; extra == 'test' - - pytest-jupyter[client]>=0.6.2 ; extra == 'test' + - pytest-jupyter[client]>=0.4.1 ; extra == 'test' - pytest-timeout ; extra == 'test' - requires_python: '>=3.10' + - pytest<8.2.0 ; extra == 'test' + requires_python: '>=3.8' - 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 @@ -5034,10 +2477,10 @@ packages: - pytest>=7.0,<9 ; extra == 'test' - requests ; extra == 'test' requires_python: '>=3.9' -- 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/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl name: jupyter-server-terminals - version: 0.5.4 - sha256: 55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14 + version: 0.5.3 + sha256: 41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa requires_dist: - pywinpty>=2.0.3 ; os_name == 'nt' - terminado>=0.8.3 @@ -5058,10 +2501,10 @@ packages: - pytest-timeout ; extra == 'test' - pytest>=7.0 ; extra == 'test' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/b9/52/372d3494766d690dfdd286871bf5f7fb9a6c61f7566ccaa7153a163dd1df/jupyterlab-4.5.5-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/6c/1e/5a4d5498eba382fee667ed797cf64ae5d1b13b04356df62f067f48bb0f61/jupyterlab-4.5.0-py3-none-any.whl name: jupyterlab - version: 4.5.5 - sha256: a35694a40a8e7f2e82f387472af24e61b22adcce87b5a8ab97a5d9c486202a6d + version: 4.5.0 + sha256: 88e157c75c1afff64c7dc4b801ec471450b922a4eae4305211ddd40da8201c8a requires_dist: - async-lru>=1.0.0 - httpx>=0.25.0,<1 @@ -5153,438 +2596,141 @@ packages: - openapi-spec-validator>=0.6.0,<0.8.0 ; extra == 'test' - pytest-console-scripts ; extra == 'test' - pytest-cov ; extra == 'test' - - pytest-jupyter[server]>=0.6.2 ; extra == 'test' - - pytest-timeout ; extra == 'test' - - pytest>=7.0,<8 ; extra == 'test' - - requests-mock ; extra == 'test' - - ruamel-yaml ; extra == 'test' - - sphinxcontrib-spelling ; extra == 'test' - - 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 - sha256: efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - name: kiwisolver - version: 1.4.9 - sha256: b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl - name: lark - version: 1.3.1 - sha256: c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12 - requires_dist: - - regex ; extra == 'regex' - - js2py ; extra == 'nearley' - - 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.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.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: 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 + - pytest-jupyter[server]>=0.6.2 ; extra == 'test' + - pytest-timeout ; extra == 'test' + - pytest>=7.0,<8 ; extra == 'test' + - requests-mock ; extra == 'test' + - ruamel-yaml ; extra == 'test' + - sphinxcontrib-spelling ; extra == 'test' + - strict-rfc3339 ; extra == 'test' + - werkzeug ; extra == 'test' + requires_python: '>=3.8' +- 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/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/ca/f0/f44f50c9f5b1a1860261092e3bc91ecdc9acda848a8b8c6abfda4a24dd5c/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl + name: kiwisolver + version: 1.4.9 + sha256: efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: kiwisolver + version: 1.4.9 + sha256: b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl + name: lark + version: 1.3.1 + sha256: c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12 + requires_dist: + - regex ; extra == 'regex' + - js2py ; extra == 'nearley' + - 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 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 + constrains: + - binutils_impl_linux-64 2.45 + license: GPL-3.0-only 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 + size: 729222 + timestamp: 1763768158810 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda + sha256: 1e1b08f6211629cbc2efe7a5bca5953f8f6b3cae0eeb04ca4dacee1bd4e2db2f + md5: 8b09ae86839581147ef2e5c5e229d164 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 constrains: - - expat 2.7.4.* + - expat 2.7.3.* license: MIT license_family: MIT purls: [] - size: 76798 - timestamp: 1771259418166 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda - sha256: 8d9d79b2de7d6f335692391f5281607221bf5d040e6724dad4c4d77cd603ce43 - md5: a684eb8a19b2aa68fde0267df172a1e3 + size: 76643 + timestamp: 1763549731408 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda + sha256: d11b3a6ce5b2e832f430fd112084533a01220597221bee16d6c7dc3947dffba6 + md5: 222e0732a1d0780a622926265bee14ef depends: - __osx >=10.13 constrains: - - expat 2.7.4.* + - expat 2.7.3.* license: MIT license_family: MIT purls: [] - size: 74578 - timestamp: 1771260142624 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda - sha256: 03887d8080d6a8fe02d75b80929271b39697ecca7628f0657d7afaea87761edf - md5: a92e310ae8dfc206ff449f362fc4217f + size: 74058 + timestamp: 1763549886493 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda + sha256: fce22610ecc95e6d149e42a42fbc3cc9d9179bd4eb6232639a60f06e080eec98 + md5: b79875dbb5b1db9a4a22a4520f918e1a depends: - __osx >=11.0 constrains: - - expat 2.7.4.* + - expat 2.7.3.* license: MIT license_family: MIT purls: [] - size: 68199 - timestamp: 1771260020767 -- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda - sha256: b31f6fb629c4e17885aaf2082fb30384156d16b48b264e454de4a06a313b533d - md5: 1c1ced969021592407f16ada4573586d + size: 67800 + timestamp: 1763549994166 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda + sha256: 844ab708594bdfbd7b35e1a67c379861bcd180d6efe57b654f482ae2f7f5c21e + md5: 8c9e4f1a0e688eef2e95711178061a0f depends: - ucrt >=10.0.20348.0 - vc >=14.3,<15 - vc14_runtime >=14.44.35208 constrains: - - expat 2.7.4.* + - expat 2.7.3.* license: MIT license_family: MIT purls: [] - size: 70323 - timestamp: 1771259521393 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 - md5: a360c33a5abe61c07959e449fa1453eb + size: 70137 + timestamp: 1763550049107 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda + sha256: 25cbdfa65580cfab1b8d15ee90b4c9f1e0d72128f1661449c9a999d341377d54 + md5: 35f29eec58405aaf55e01cb470d8c26a depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 58592 - timestamp: 1769456073053 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda - sha256: 951958d1792238006fdc6fce7f71f1b559534743b26cc1333497d46e5903a2d6 - md5: 66a0dc7464927d0853b590b6f53ba3ea + size: 57821 + timestamp: 1760295480630 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda + sha256: 277dc89950f5d97f1683f26e362d6dca3c2efa16cb2f6fdb73d109effa1cd3d0 + md5: d214916b24c625bcc459b245d509f22e depends: - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 53583 - timestamp: 1769456300951 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - sha256: 6686a26466a527585e6a75cc2a242bf4a3d97d6d6c86424a441677917f28bec7 - md5: 43c04d9cb46ef176bb2a4c77e324d599 + size: 52573 + timestamp: 1760295626449 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda + sha256: 9b8acdf42df61b7bfe8bdc545c016c29e61985e79748c64ad66df47dbc2e295f + md5: 411ff7cd5d1472bba0f55c0faf04453b depends: - __osx >=11.0 license: MIT license_family: MIT purls: [] - size: 40979 - timestamp: 1769456747661 -- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda - sha256: 59d01f2dfa8b77491b5888a5ab88ff4e1574c9359f7e229da254cdfe27ddc190 - md5: 720b39f5ec0610457b725eb3f396219a + size: 40251 + timestamp: 1760295839166 +- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda + sha256: ddff25aaa4f0aa535413f5d831b04073789522890a4d8626366e43ecde1534a3 + md5: ba4ad812d2afc22b9a34ce8327a0930f depends: - ucrt >=10.0.20348.0 - vc >=14.3,<15 @@ -5592,300 +2738,210 @@ packages: license: MIT license_family: MIT purls: [] - size: 45831 - timestamp: 1769456418774 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 - md5: 0aa00f03f9e39fb9876085dee11a85d4 + size: 44866 + timestamp: 1760295760649 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda + sha256: 08f9b87578ab981c7713e4e6a7d935e40766e10691732bba376d4964562bcb45 + md5: c0374badb3a5d4b1372db28d19462c53 depends: - __glibc >=2.17,<3.0.a0 - _openmp_mutex >=4.5 constrains: - - libgcc-ng ==15.2.0=*_18 - - libgomp 15.2.0 he0feb66_18 + - libgomp 15.2.0 h767d61c_7 + - libgcc-ng ==15.2.0=*_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - 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 + 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 depends: - - libgcc 15.2.0 he0feb66_18 + - libgcc 15.2.0 h767d61c_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 27526 - timestamp: 1771378224552 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 - md5: 239c5e9546c38a1e884d69effcf4c882 + size: 29313 + timestamp: 1759968065504 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda + sha256: e9fb1c258c8e66ee278397b5822692527c5f5786d372fe7a869b900853f3f5ca + md5: f7b4d76975aac7e5d9e6ad13845f92fe depends: - __glibc >=2.17,<3.0.a0 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 603262 - timestamp: 1771378117851 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda - sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb - md5: c7c83eecbb72d88b940c249af56c8b17 + size: 447919 + timestamp: 1759967942498 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda + sha256: f2591c0069447bbe28d4d696b7fcb0c5bd0b4ac582769b89addbcf26fb3430d8 + md5: 1a580f7796c7bf6393fddb8bbbde58dc depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=14 + - libgcc >=13 constrains: - - xz 5.8.2.* + - xz 5.8.1.* license: 0BSD purls: [] - size: 113207 - timestamp: 1768752626120 -- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda - sha256: 7ab3c98abd3b5d5ec72faa8d9f5d4b50dcee4970ed05339bc381861199dabb41 - md5: 688a0c3d57fa118b9c97bf7e471ab46c + size: 112894 + timestamp: 1749230047870 +- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda + sha256: 7e22fd1bdb8bf4c2be93de2d4e718db5c548aa082af47a7430eb23192de6bb36 + md5: 8468beea04b9065b9807fc8b9cdc5894 depends: - __osx >=10.13 constrains: - - xz 5.8.2.* + - xz 5.8.1.* license: 0BSD purls: [] - size: 105482 - timestamp: 1768753411348 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda - sha256: 7bfc7ffb2d6a9629357a70d4eadeadb6f88fa26ebc28f606b1c1e5e5ed99dc7e - md5: 009f0d956d7bfb00de86901d16e486c7 + size: 104826 + timestamp: 1749230155443 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda + sha256: 0cb92a9e026e7bd4842f410a5c5c665c89b2eb97794ffddba519a626b8ce7285 + md5: d6df911d4564d77c4374b02552cb17d1 depends: - __osx >=11.0 constrains: - - xz 5.8.2.* + - xz 5.8.1.* license: 0BSD purls: [] - size: 92242 - timestamp: 1768752982486 -- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda - sha256: f25bf293f550c8ed2e0c7145eb404324611cfccff37660869d97abf526eb957c - md5: ba0bfd4c3cf73f299ffe46ff0eaeb8e3 + size: 92286 + timestamp: 1749230283517 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda + sha256: 55764956eb9179b98de7cc0e55696f2eff8f7b83fc3ebff5e696ca358bca28cc + md5: c15148b2e18da456f5108ccb5e411446 depends: - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 constrains: - - xz 5.8.2.* + - xz 5.8.1.* license: 0BSD purls: [] - size: 106169 - timestamp: 1768752763559 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda - sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843 - md5: 2c21e66f50753a083cbe6b80f38268fa + size: 104935 + timestamp: 1749230611612 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda + sha256: 3aa92d4074d4063f2a162cd8ecb45dccac93e543e565c01a787e16a43501f7ee + md5: c7e925f37e3b40d893459e625f6a53f1 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=14 + - libgcc >=13 license: BSD-2-Clause license_family: BSD purls: [] - size: 92400 - timestamp: 1769482286018 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda - sha256: 1096c740109386607938ab9f09a7e9bca06d86770a284777586d6c378b8fb3fd - md5: ec88ba8a245855935b871a7324373105 + size: 91183 + timestamp: 1748393666725 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda + sha256: 98299c73c7a93cd4f5ff8bb7f43cd80389f08b5a27a296d806bdef7841cc9b9e + md5: 18b81186a6adb43f000ad19ed7b70381 depends: - __osx >=10.13 license: BSD-2-Clause license_family: BSD purls: [] - size: 79899 - timestamp: 1769482558610 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda - sha256: 1089c7f15d5b62c622625ec6700732ece83be8b705da8c6607f4dabb0c4bd6d2 - md5: 57c4be259f5e0b99a5983799a228ae55 + size: 77667 + timestamp: 1748393757154 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda + sha256: 0a1875fc1642324ebd6c4ac864604f3f18f57fbcf558a8264f6ced028a3c75b2 + md5: 85ccccb47823dd9f7a99d2c7f530342f depends: - __osx >=11.0 license: BSD-2-Clause license_family: BSD purls: [] - size: 73690 - timestamp: 1769482560514 -- conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda - sha256: 40dcd0b9522a6e0af72a9db0ced619176e7cfdb114855c7a64f278e73f8a7514 - md5: e4a9fc2bba3b022dad998c78856afe47 + size: 71829 + timestamp: 1748393749336 +- conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda + sha256: fc529fc82c7caf51202cc5cec5bb1c2e8d90edbac6d0a4602c966366efe3c7bf + md5: 74860100b2029e2523cf480804c76b9b depends: - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: BSD-2-Clause license_family: BSD purls: [] - 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 + size: 88657 + timestamp: 1723861474602 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda + sha256: 4c992dcd0e34b68f843e75406f7f303b1b97c248d18f3c7c330bdc0bc26ae0b3 + md5: 729a572a3ebb8c43933b30edcc628ceb 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 >=78.2,<79.0a0 + - icu >=75.1,<76.0a0 - libgcc >=14 - libzlib >=1.3.1,<2.0a0 license: blessing purls: [] - size: 942808 - timestamp: 1768147973361 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda - sha256: 710a7ea27744199023c92e66ad005de7f8db9cf83f10d5a943d786f0dac53b7c - md5: d910105ce2b14dfb2b32e92ec7653420 + size: 945576 + timestamp: 1762299687230 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.0-h86bffb9_0.conda + sha256: ad151af8192c17591fad0b68c9ffb7849ad9f4be9da2020b38b8befd2c5f6f02 + md5: 1ee9b74571acd6dd87e6a0f783989426 depends: - __osx >=10.13 - libzlib >=1.3.1,<2.0a0 license: blessing purls: [] - size: 987506 - timestamp: 1768148247615 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda - sha256: 6e9b9f269732cbc4698c7984aa5b9682c168e2a8d1e0406e1ff10091ca046167 - md5: 4b0bf313c53c3e89692f020fb55d5f2c + size: 986898 + timestamp: 1762300146976 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.0-h8adb53f_0.conda + sha256: b43d198f147f46866e5336c4a6b91668beef698bfba69d1706158460eadb2c1b + md5: 5fb1945dbc6380e6fe7e939a62267772 depends: - __osx >=11.0 - - icu >=78.2,<79.0a0 + - icu >=75.1,<76.0a0 - libzlib >=1.3.1,<2.0a0 license: blessing purls: [] - size: 909777 - timestamp: 1768148320535 -- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda - sha256: 756478128e3e104bd7e7c3ce6c1b0efad7e08c7320c69fdc726e039323c63fbb - md5: 903979414b47d777d548e5f0165e6cd8 + size: 909508 + timestamp: 1762300078624 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.0-hf5d6505_0.conda + sha256: 2373bd7450693bd0f624966e1bee2f49b0bf0ffbc114275ed0a43cf35aec5b21 + md5: d2c9300ebd2848862929b18c264d1b1e depends: - ucrt >=10.0.20348.0 - vc >=14.3,<15 - vc14_runtime >=14.44.35208 license: blessing purls: [] - size: 1291616 - timestamp: 1768148278261 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e - md5: 1b08cd684f34175e4514474793d44bcb + size: 1292710 + timestamp: 1762299749044 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda + sha256: 1b981647d9775e1cdeb2fab0a4dd9cd75a6b0de2963f6c3953dbd712f78334b3 + md5: 5b767048b1b3ee9a954b06f4084f93dc depends: - __glibc >=2.17,<3.0.a0 - - libgcc 15.2.0 he0feb66_18 + - libgcc 15.2.0 h767d61c_7 constrains: - - libstdcxx-ng ==15.2.0=*_18 + - libstdcxx-ng ==15.2.0=*_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 5852330 - timestamp: 1771378262446 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda - sha256: 1a7539cfa7df00714e8943e18de0b06cceef6778e420a5ee3a2a145773758aee - md5: db409b7c1720428638e7c0d509d3e1b5 + 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: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: BSD-3-Clause - license_family: BSD + - libstdcxx 15.2.0 h8f9b012_7 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL purls: [] - size: 40311 - timestamp: 1766271528534 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda - sha256: c180f4124a889ac343fc59d15558e93667d894a966ec6fdb61da1604481be26b - md5: 0f03292cc56bf91a077a134ea8747118 + size: 29343 + timestamp: 1759968157195 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda + sha256: e5ec6d2ad7eef538ddcb9ea62ad4346fde70a4736342c4ad87bd713641eb9808 + md5: 80c07c68d2f6870250959dcc95b209d1 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 + license: BSD-3-Clause + license_family: BSD purls: [] - size: 100393 - timestamp: 1702724383534 + size: 37135 + timestamp: 1758626800002 - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 md5: edb0dca6bc32e4f4789199455a1dbeb8 @@ -5972,88 +3028,16 @@ packages: - pytest-cov ; extra == 'test' - lmfit[dev,doc,test] ; extra == 'all' requires_python: '>=3.9' -- 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: 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 @@ -6064,91 +3048,10 @@ packages: version: 3.0.3 sha256: ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 requires_python: '>=3.9' -- 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 +- pypi: https://files.pythonhosted.org/packages/02/9c/207547916a02c78f6bdd83448d9b21afbc42f6379ed887ecf610984f3b4e/matplotlib-3.10.7-cp313-cp313-macosx_10_13_x86_64.whl name: matplotlib - version: 3.10.8 - sha256: 56271f3dac49a88d7fca5060f004d9d22b865f743a12a23b1e937a0be4818ee1 + version: 3.10.7 + sha256: 1d9d3713a237970569156cfb4de7533b7c4eacdd61789726f444f96a0d28f57f requires_dist: - contourpy>=1.0.1 - cycler>=0.10 @@ -6164,10 +3067,10 @@ packages: - setuptools-scm>=7 ; extra == 'dev' - setuptools>=64 ; extra == 'dev' requires_python: '>=3.10' -- 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/22/ff/6425bf5c20d79aa5b959d1ce9e65f599632345391381c9a104133fe0b171/matplotlib-3.10.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl name: matplotlib - version: 3.10.8 - sha256: efb30e3baaea72ce5928e32bab719ab4770099079d66726a62b11b1ef7273be4 + version: 3.10.7 + sha256: b3c4ea4948d93c9c29dc01c0c23eef66f2101bf75158c291b88de6525c55c3d1 requires_dist: - contourpy>=1.0.1 - cycler>=0.10 @@ -6183,10 +3086,10 @@ packages: - setuptools-scm>=7 ; extra == 'dev' - setuptools>=64 ; extra == 'dev' requires_python: '>=3.10' -- 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/bc/d0/b3d3338d467d3fc937f0bb7f256711395cae6f78e22cef0656159950adf0/matplotlib-3.10.7-cp313-cp313-macosx_11_0_arm64.whl name: matplotlib - version: 3.10.8 - sha256: 6be43b667360fef5c754dda5d25a32e6307a03c204f3c0fc5468b78fa87b4160 + version: 3.10.7 + sha256: 37a1fea41153dd6ee061d21ab69c9cf2cf543160b1b85d89cd3d2e2a7902ca4c requires_dist: - contourpy>=1.0.1 - cycler>=0.10 @@ -6202,10 +3105,10 @@ packages: - setuptools-scm>=7 ; extra == 'dev' - setuptools>=64 ; extra == 'dev' requires_python: '>=3.10' -- 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/e1/b6/23064a96308b9aeceeffa65e96bcde459a2ea4934d311dee20afde7407a0/matplotlib-3.10.7-cp313-cp313-win_amd64.whl name: matplotlib - version: 3.10.8 - sha256: a2b336e2d91a3d7006864e0990c83b216fcdca64b5a6484912902cef87313d78 + version: 3.10.7 + sha256: 744991e0cc863dd669c8dc9136ca4e6e0082be2070b9d793cbd64bec872a6815 requires_dist: - contourpy>=1.0.1 - cycler>=0.10 @@ -6233,211 +3136,25 @@ packages: - notebook ; extra == 'test' - pytest ; extra == 'test' requires_python: '>=3.9' -- 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 +- 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 requires_python: '>=3.6' -- 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 +- pypi: https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl name: mistune - version: 3.2.0 - sha256: febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1 + version: 3.1.4 + sha256: 93691da911e5d9d2e23bc54472892aff676df27a75274962ff9edc210364266d 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 sha256: bea31799a4041029a906f53f2662bbf1c49903e0c0bc712b412354158ec7cf54 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' + - matplotlib - 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 @@ -6453,155 +3170,45 @@ 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/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 +- pypi: https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl name: multidict - version: 6.7.1 - sha256: 960c83bf01a95b12b08fd54324a4eb1d5b52c88932b5cba5d6e712bb3ed12eb5 + version: 6.7.0 + sha256: 30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390 requires_dist: - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- 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/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl name: multidict - version: 6.7.1 - sha256: 84e61e3af5463c19b67ced91f6c634effb89ef8bfc5ca0267f954451ed4bb6a2 + version: 6.7.0 + sha256: 7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159 requires_dist: - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/c9/68/f16a3a8ba6f7b6dc92a1f19669c0810bd2c43fc5a02da13b1cbf8e253845/multidict-6.7.1-cp311-cp311-win_amd64.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 name: multidict - version: 6.7.1 - sha256: bdbf9f3b332abd0cdb306e7c2113818ab1e922dc84b8f8fd06ec89ed2a19ab8b + version: 6.7.0 + sha256: 9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32 requires_dist: - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- 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/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl name: multidict - version: 6.7.1 - sha256: f2a0a924d4c2e9afcd7ec64f9de35fcd96915149b2216e1cb2c10a56df483855 + version: 6.7.0 + sha256: 9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca requires_dist: - typing-extensions>=4.1.0 ; python_full_version < '3.11' requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/4b/27/20770bd6bf8fbe1e16f848ba21da9df061f38d2e6483952c29d2bb5d1d8b/narwhals-2.17.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/0b/9a/c6f79de7ba3a0a8473129936b7b90aa461d3d46fec6f1627672b1dccf4e9/narwhals-2.12.0-py3-none-any.whl name: narwhals - version: 2.17.0 - sha256: 2ac5307b7c2b275a7d66eeda906b8605e3d7a760951e188dcfff86e8ebe083dd + version: 2.12.0 + sha256: baeba5d448a30b04c299a696bd9ee5ff73e4742143e06c49ca316b46539a7cbb requires_dist: - - cudf-cu12>=24.10.0 ; extra == 'cudf' + - cudf>=24.10.0 ; extra == 'cudf' - dask[dataframe]>=2024.8 ; extra == 'dask' - duckdb>=1.1 ; extra == 'duckdb' - ibis-framework>=6.0.0 ; extra == 'ibis' @@ -6614,18 +3221,16 @@ 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/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl name: nbclient - version: 0.10.4 - sha256: 9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440 + version: 0.10.2 + sha256: 4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d requires_dist: - jupyter-client>=6.1.12 - jupyter-core>=4.12,!=5.0.* - - nbformat>=5.1.3 + - nbformat>=5.1 - traitlets>=5.4 - pre-commit ; extra == 'dev' - autodoc-traits ; extra == 'docs' @@ -6637,9 +3242,9 @@ packages: - moto ; extra == 'docs' - myst-parser ; extra == 'docs' - nbconvert>=7.1.0 ; extra == 'docs' - - pytest-asyncio>=1.3.0 ; extra == 'docs' + - pytest-asyncio ; extra == 'docs' - pytest-cov>=4.0 ; extra == 'docs' - - pytest>=9.0.1,<10 ; extra == 'docs' + - pytest>=7.0,<8 ; extra == 'docs' - sphinx-book-theme ; extra == 'docs' - sphinx>=1.7 ; extra == 'docs' - sphinxcontrib-spelling ; extra == 'docs' @@ -6650,16 +3255,16 @@ packages: - ipython ; extra == 'test' - ipywidgets ; extra == 'test' - nbconvert>=7.1.0 ; extra == 'test' - - pytest-asyncio>=1.3.0 ; extra == 'test' + - pytest-asyncio ; extra == 'test' - pytest-cov>=4.0 ; extra == 'test' - - pytest>=9.0.1,<10 ; extra == 'test' + - pytest>=7.0,<8 ; extra == 'test' - testpath ; extra == 'test' - xmltodict ; extra == 'test' - requires_python: '>=3.10.0' -- pypi: https://files.pythonhosted.org/packages/0d/4b/8d5f796a792f8a25f6925a96032f098789f448571eb92011df1ae59e8ea8/nbconvert-7.17.0-py3-none-any.whl + requires_python: '>=3.9.0' +- pypi: https://files.pythonhosted.org/packages/cc/9a/cd673b2f773a12c992f41309ef81b99da1690426bd2f96957a7ade0d3ed7/nbconvert-7.16.6-py3-none-any.whl name: nbconvert - version: 7.17.0 - sha256: 4f99a63b337b9a23504347afdab24a11faa7d86b405e5c8f9881cd313336d518 + version: 7.16.6 + sha256: 1375a7b67e0c2883678c48e506dc320febb57685e5ee67faa51b18a90f3a712b requires_dist: - beautifulsoup4 - bleach[css]!=5.0.0 @@ -6677,7 +3282,6 @@ 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' @@ -6687,16 +3291,15 @@ 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' @@ -6706,7 +3309,7 @@ packages: - ipywidgets>=7.5 ; extra == 'test' - pytest>=7 ; extra == 'test' - playwright ; extra == 'webpdf' - requires_python: '>=3.9' + requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl name: nbformat version: 5.10.4 @@ -6726,43 +3329,6 @@ 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 @@ -6796,92 +3362,21 @@ packages: version: 1.6.0 sha256: 87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c requires_python: '>=3.5' -- 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/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/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl name: notebook-shim version: 0.2.4 @@ -6893,49 +3388,29 @@ packages: - pytest-jupyter ; extra == 'test' - pytest-tornasync ; extra == 'test' requires_python: '>=3.7' -- 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.4.2 - sha256: bd3a7a9f5847d2fb8c2c6d1c862fa109c31a9abeca1a3c2bd5a64572955b2979 - requires_python: '>=3.11' -- 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.4.2 - sha256: c02ef4401a506fb60b411467ad501e1429a3487abca4664871d9ae0b46c8ba32 - requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/43/bc/6352f343522fcb2c04dbaf94cb30cca6fd32c1a750c06ad6231b4293708c/numpy-2.4.2-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl name: numpy - version: 2.4.2 - sha256: 7df2de1e4fba69a51c06c28f5a3de36731eb9639feb8e1cf7e4a7b0daf4cf622 + version: 2.3.5 + sha256: 00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b requires_python: '>=3.11' -- 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/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl name: numpy - version: 2.4.2 - sha256: 7edc794af8b36ca37ef5fcb5e0d128c7e0595c7b96a2318d1badb6fcd8ee86b1 + version: 2.3.5 + sha256: aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188 requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/76/ae/e0265e0163cf127c24c3969d29f1c4c64551a1e375d95a13d32eab25d364/numpy-2.4.2-cp311-cp311-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl name: numpy - version: 2.4.2 - sha256: b9c618d56a29c9cb1c4da979e9899be7578d2e0b3c24d52079c166324c9e8695 + version: 2.3.5 + sha256: d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff 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 +- 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 name: numpy - version: 2.4.2 - sha256: 25f2059807faea4b077a2b6837391b5d830864b3543627f381821c646f31a63c + version: 2.3.5 + sha256: 11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017 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 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda + sha256: a47271202f4518a484956968335b2521409c8173e123ab381e775c358c67fe6d + md5: 9ee58d5c534af06558933af3c845a780 depends: - __glibc >=2.17,<3.0.a0 - ca-certificates @@ -6943,33 +3418,33 @@ packages: license: Apache-2.0 license_family: Apache purls: [] - size: 3164551 - timestamp: 1769555830639 -- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda - sha256: e02e5639b0e4d6d4fcf0f3b082642844fb5a37316f5b0a1126c6271347462e90 - md5: 30bb8d08b99b9a7600d39efb3559fff0 + size: 3165399 + timestamp: 1762839186699 +- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda + sha256: 36fe9fb316be22fcfb46d5fa3e2e85eec5ef84f908b7745f68f768917235b2d5 + md5: 3f50cdf9a97d0280655758b735781096 depends: - __osx >=10.13 - ca-certificates license: Apache-2.0 license_family: Apache purls: [] - size: 2777136 - timestamp: 1769557662405 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda - sha256: 361f5c5e60052abc12bdd1b50d7a1a43e6a6653aab99a2263bf2288d709dcf67 - md5: f4f6ad63f98f64191c3e77c5f5f29d76 + size: 2778996 + timestamp: 1762840724922 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda + sha256: ebe93dafcc09e099782fe3907485d4e1671296bc14f8c383cb6f3dfebb773988 + md5: b34dc4172653c13dcf453862f251af2b depends: - __osx >=11.0 - ca-certificates license: Apache-2.0 license_family: Apache purls: [] - size: 3104268 - timestamp: 1769556384749 -- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda - sha256: 53a5ad2e5553b8157a91bb8aa375f78c5958f77cb80e9d2ce59471ea8e5c0bd6 - md5: eb585509b815415bc964b2c7e11c7eb3 + size: 3108371 + timestamp: 1762839712322 +- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda + sha256: 6d72d6f766293d4f2aa60c28c244c8efed6946c430814175f959ffe8cab899b3 + md5: 84f8fb4afd1157f59098f618cd2437e4 depends: - ca-certificates - ucrt >=10.0.20348.0 @@ -6978,913 +3453,408 @@ packages: license: Apache-2.0 license_family: Apache purls: [] - 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 + size: 9440812 + timestamp: 1762841722179 +- pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl name: packaging - version: '26.0' - sha256: b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 + version: '25.0' + sha256: 29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 requires_python: '>=3.8' -- 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 +- 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 name: pandas - version: 3.0.1 - sha256: 24ba315ba3d6e5806063ac6eb717504e499ce30bd8c236d8693a5fd3f084c796 + version: 2.3.3 + sha256: 318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' + - 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' - 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' + - 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' - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.5 ; extra == 'excel' - - python-calamine>=0.3.0 ; extra == 'excel' + - openpyxl>=3.1.0 ; extra == 'excel' + - python-calamine>=0.1.7 ; 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' + - 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' - 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' + - 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' - 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' + - 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' - 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' + - 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' - 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' + - 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' - 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' + - 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' - 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' + - 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' - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2024.10.0 ; extra == 'all' + - xarray>=2022.12.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/d6/7d/216a1588b65a7aa5f4535570418a599d943c85afb1d95b0876fc00aa1468/pandas-3.0.1-cp313-cp313-win_amd64.whl + - 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 name: pandas - version: 3.0.1 - sha256: 9fea306c783e28884c29057a1d9baa11a349bbf99538ec1da44c8476563d1b25 + version: 2.3.3 + sha256: bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8 requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' + - 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' - 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' + - 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' - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.5 ; extra == 'excel' - - python-calamine>=0.3.0 ; extra == 'excel' + - openpyxl>=3.1.0 ; extra == 'excel' + - python-calamine>=0.1.7 ; 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' + - 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' - 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' + - 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' - 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' + - 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' - 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' + - 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' - 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' + - 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' - 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' + - 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' - 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' + - 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' - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2024.10.0 ; extra == 'all' + - xarray>=2022.12.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/f2/85/ab6d04733a7d6ff32bfc8382bf1b07078228f5d6ebec5266b91bfc5c4ff7/pandas-3.0.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - 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 name: pandas - version: 3.0.1 - sha256: 1ff8cf1d2896e34343197685f432450ec99a85ba8d90cce2030c5eee2ef98791 + version: 2.3.3 + sha256: f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' + - 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' - 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' + - 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' - odfpy>=1.4.1 ; extra == 'excel' - - openpyxl>=3.1.5 ; extra == 'excel' - - python-calamine>=0.3.0 ; extra == 'excel' + - openpyxl>=3.1.0 ; extra == 'excel' + - python-calamine>=0.1.7 ; 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' + - 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' - 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' + - 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' - 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' + - 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' - 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' + - 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' - 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' + - 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' - 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' + - 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' - 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' + - 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' - tabulate>=0.9.0 ; extra == 'all' - - xarray>=2024.10.0 ; extra == 'all' + - xarray>=2022.12.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/ff/07/c7087e003ceee9b9a82539b40414ec557aa795b584a1a346e89180853d79/pandas-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl + - 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 name: pandas - version: 3.0.1 - sha256: de09668c1bf3b925c07e5762291602f0d789eca1b3a781f99c1c78f6cac0e7ea + version: 2.3.3 + sha256: 56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713 requires_dist: - - numpy>=1.26.0 ; python_full_version < '3.14' - - numpy>=2.3.3 ; python_full_version >= '3.14' + - 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' - 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/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/b6/61/fae042894f4296ec49e3f193aff5d7c18440da9e48102c3315e1bc4519a7/parso-0.8.6-py2.py3-none-any.whl - name: parso - version: 0.8.6 - sha256: 2c549f800b70a5c4952197248825584cb00f033b29c692671d3bf08bf380baff - requires_dist: - - pytest ; extra == 'testing' - - docopt ; extra == 'testing' - - flake8==5.0.4 ; 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/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl - name: pathspec - 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/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 + - 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' + - odfpy>=1.4.1 ; extra == 'excel' + - openpyxl>=3.1.0 ; extra == 'excel' + - python-calamine>=0.1.7 ; 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' + - 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' + - 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' + - 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' + - 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' + - 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' + - 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' + - tabulate>=0.9.0 ; extra == 'all' + - xarray>=2022.12.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/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 + name: parso + version: 0.8.5 + sha256: 646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887 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 + - pytest ; extra == 'testing' + - docopt ; extra == 'testing' + - flake8==5.0.4 ; extra == 'qa' + - mypy==0.971 ; 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 + name: pathspec + version: 0.12.1 + sha256: a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08 + requires_python: '>=3.8' +- 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: - - 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 + - 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 name: pillow - version: 12.1.1 - sha256: 47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717 + version: 12.0.0 + sha256: f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344 requires_dist: - furo ; extra == 'docs' - olefile ; extra == 'docs' @@ -7913,10 +3883,10 @@ packages: - trove-classifiers>=2024.10.12 ; extra == 'tests' - defusedxml ; extra == 'xmp' requires_python: '>=3.10' -- 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/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl name: pillow - version: 12.1.1 - sha256: 365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38 + version: 12.0.0 + sha256: 4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905 requires_dist: - furo ; extra == 'docs' - olefile ; extra == 'docs' @@ -7945,10 +3915,10 @@ packages: - trove-classifiers>=2024.10.12 ; extra == 'tests' - defusedxml ; extra == 'xmp' requires_python: '>=3.10' -- 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/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl name: pillow - version: 12.1.1 - sha256: 597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b + version: 12.0.0 + sha256: 5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b requires_dist: - furo ; extra == 'docs' - olefile ; extra == 'docs' @@ -7977,10 +3947,10 @@ packages: - trove-classifiers>=2024.10.12 ; extra == 'tests' - defusedxml ; extra == 'xmp' requires_python: '>=3.10' -- 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/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl name: pillow - version: 12.1.1 - sha256: 8b7e5304e34942bf62e15184219a7b5ad4ff7f3bb5cca4d984f37df1a0e1aee2 + version: 12.0.0 + sha256: c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5 requires_dist: - furo ; extra == 'docs' - olefile ; extra == 'docs' @@ -8009,27 +3979,26 @@ packages: - trove-classifiers>=2024.10.12 ; extra == 'tests' - defusedxml ; extra == 'xmp' requires_python: '>=3.10' -- 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 +- pypi: https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl name: platformdirs - version: 4.9.2 - sha256: 9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd + 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' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/52/d2/c6e44dba74f17c6216ce1b56044a9b93a929f1c2d5bdaff892512b260f5e/plotly-6.6.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/e7/c3/3031c931098de393393e1f93a38dc9ed6805d86bb801acc3cf2d5bd1e6b7/plotly-6.5.0-py3-none-any.whl name: plotly - version: 6.6.0 - sha256: 8d6daf0f87412e0c0bfe72e809d615217ab57cc715899a1e5145135a7800d1d0 + version: 6.5.0 + sha256: 5ac851e100367735250206788a2b1325412aa4a4917a4fe3e6f0bc5aa6f3d90a requires_dist: - narwhals>=1.15.1 - packaging @@ -8077,47 +4046,12 @@ packages: - pytest-benchmark ; extra == 'testing' - coverage ; extra == 'testing' requires_python: '>=3.9' -- 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 +- pypi: https://files.pythonhosted.org/packages/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.1-py3-none-any.whl name: prometheus-client - version: 0.24.1 - sha256: 150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 + version: 0.23.1 + sha256: dd1913e6e76b59cfe44e7a4b83e01afc9873c1bdfd2ed8739f1e76aeca115f99 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 @@ -8126,11 +4060,6 @@ 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 @@ -8141,39 +4070,24 @@ 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/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/55/4c/c3ed1a622b6ae2fd3c945a366e64eb35247a31e4db16cf5095e269e8eb3c/psutil-7.1.3-cp37-abi3-win_amd64.whl name: psutil - version: 7.2.2 - sha256: 1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979 + version: 7.1.3 + sha256: f39c2c19fe824b47484b96f9692932248a54c43799a84282cfe58d05a6449efd 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' @@ -8197,27 +4111,27 @@ packages: - vulture ; extra == 'dev' - wheel ; extra == 'dev' - colorama ; os_name == 'nt' 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' + - 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' - pytest ; extra == 'test' - pytest-instafail ; extra == 'test' + - pytest-subtests ; extra == 'test' - pytest-xdist ; extra == 'test' - setuptools ; 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' + - 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' requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/68/3a/9f93cff5c025029a36d9a92fef47220ab4692ee7f2be0fba9f92813d0cb8/psutil-7.1.3-cp36-abi3-macosx_11_0_arm64.whl name: psutil - version: 7.2.2 - sha256: eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988 + version: 7.1.3 + sha256: bc31fa00f1fbc3c3802141eede66f3a2d51d89716a194bf2cd6fc68310a19880 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' @@ -8241,27 +4155,27 @@ packages: - vulture ; extra == 'dev' - wheel ; extra == 'dev' - colorama ; os_name == 'nt' 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' + - 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' - pytest ; extra == 'test' - pytest-instafail ; extra == 'test' + - pytest-subtests ; extra == 'test' - pytest-xdist ; extra == 'test' - setuptools ; 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' + - 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' requires_python: '>=3.6' -- 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/ce/b1/5f49af514f76431ba4eea935b8ad3725cdeb397e9245ab919dbc1d1dc20f/psutil-7.1.3-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl name: psutil - version: 7.2.2 - sha256: 076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9 + version: 7.1.3 + sha256: 3bb428f9f05c1225a558f53e30ccbad9930b11c3fc206836242de1091d3e7dd3 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' @@ -8285,27 +4199,27 @@ packages: - vulture ; extra == 'dev' - wheel ; extra == 'dev' - colorama ; os_name == 'nt' 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' + - 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' - pytest ; extra == 'test' - pytest-instafail ; extra == 'test' + - pytest-subtests ; extra == 'test' - pytest-xdist ; extra == 'test' - setuptools ; 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' + - 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' requires_python: '>=3.6' -- 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/ef/94/46b9154a800253e7ecff5aaacdf8ebf43db99de4a2dfa18575b02548654e/psutil-7.1.3-cp36-abi3-macosx_10_9_x86_64.whl name: psutil - version: 7.2.2 - sha256: ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 + version: 7.1.3 + sha256: 2bdbcd0e58ca14996a42adf3621a6244f1bb2e2e528886959c72cf1e326677ab 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' @@ -8329,18 +4243,18 @@ packages: - vulture ; extra == 'dev' - wheel ; extra == 'dev' - colorama ; os_name == 'nt' 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' + - 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' - pytest ; extra == 'test' - pytest-instafail ; extra == 'test' + - pytest-subtests ; extra == 'test' - pytest-xdist ; extra == 'test' - setuptools ; 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' + - 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' requires_python: '>=3.6' - pypi: https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl name: ptyprocess @@ -8352,88 +4266,73 @@ 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/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl name: pycparser - 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: - - 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/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 + 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 requires_dist: - - typing-extensions>=4.14.1 + - 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' 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 +- 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 requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl name: pygments @@ -8442,32 +4341,38 @@ packages: requires_dist: - colorama>=0.4.6 ; extra == 'windows-terminal' requires_python: '>=3.8' -- 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 +- pypi: https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl name: pyparsing - version: 3.3.2 - sha256: 850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d + version: 3.2.5 + sha256: e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e 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/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl name: pytest - version: 9.0.2 - sha256: 711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b + version: 9.0.1 + sha256: 67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad requires_dist: - colorama>=0.4 ; sys_platform == 'win32' - exceptiongroup>=1 ; python_full_version < '3.11' @@ -8496,202 +4401,94 @@ packages: - pytest-xdist ; extra == 'testing' - virtualenv ; extra == 'testing' requires_python: '>=3.9' -- 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.3,<3.0a0 - - libffi >=3.5.2,<3.6.0a0 - - libgcc >=14 - - 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 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda + build_number: 101 + sha256: e89da062abd0d3e76c8d3b35d3cafc5f0d05914339dcb238f9e3675f2a58d883 + md5: 4780fe896e961722d0623fa91d0d3378 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 + - libexpat >=2.7.1,<3.0a0 - libffi >=3.5.2,<3.6.0a0 - libgcc >=14 - - liblzma >=5.8.2,<6.0a0 + - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.51.2,<4.0a0 - - libuuid >=2.41.3,<3.0a0 + - libsqlite >=3.50.4,<4.0a0 + - libuuid >=2.41.2,<3.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.5.5,<4.0a0 + - openssl >=3.5.4,<4.0a0 - python_abi 3.13.* *_cp313 - - readline >=8.3,<9.0a0 + - readline >=8.2,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata license: Python-2.0 purls: [] - size: 37364553 - timestamp: 1770272309861 + size: 37174029 + timestamp: 1761178179147 python_site_packages_path: lib/python3.13/site-packages -- 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.3,<3.0a0 - - libffi >=3.5.2,<3.6.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 +- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.9-h17c18a5_101_cp313.conda + build_number: 101 + sha256: b56484229cf83f6c84e8b138dc53f7f2fa9ee850f42bf1f6d6fa1c03c044c2d3 + md5: fb1e51574ce30d2a4d5e4facb9b2cbd5 depends: - __osx >=10.13 - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.3,<3.0a0 + - libexpat >=2.7.1,<3.0a0 - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.2,<6.0a0 + - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.51.2,<4.0a0 + - libsqlite >=3.50.4,<4.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.5.5,<4.0a0 + - openssl >=3.5.4,<4.0a0 - python_abi 3.13.* *_cp313 - - readline >=8.3,<9.0a0 + - readline >=8.2,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata license: Python-2.0 purls: [] - size: 17570178 - timestamp: 1770272361922 + size: 17521522 + timestamp: 1761177097697 python_site_packages_path: lib/python3.13/site-packages -- 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.3,<3.0a0 - - libffi >=3.5.2,<3.6.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 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.9-hfc2f54d_101_cp313.conda + build_number: 101 + sha256: 516229f780b98783a5ef4112a5a4b5e5647d4f0177c4621e98aa60bb9bc32f98 + md5: a4241bce59eecc74d4d2396e108c93b8 depends: - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.3,<3.0a0 + - libexpat >=2.7.1,<3.0a0 - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.2,<6.0a0 + - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.51.2,<4.0a0 + - libsqlite >=3.50.4,<4.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.5.5,<4.0a0 + - openssl >=3.5.4,<4.0a0 - python_abi 3.13.* *_cp313 - - readline >=8.3,<9.0a0 + - readline >=8.2,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata license: Python-2.0 purls: [] - size: 12770674 - timestamp: 1770272314517 + size: 11915380 + timestamp: 1761176793936 python_site_packages_path: lib/python3.13/site-packages -- 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.3,<3.0a0 - - libffi >=3.5.2,<3.6.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 +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.9-h09917c8_101_cp313.conda + build_number: 101 + sha256: bc855b513197637c2083988d5cbdcc407a23151cdecff381bd677df33d516a01 + md5: 89d992b9d4b9e88ed54346c9c4a24c1c depends: - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.3,<3.0a0 + - libexpat >=2.7.1,<3.0a0 - libffi >=3.5.2,<3.6.0a0 - - liblzma >=5.8.2,<6.0a0 + - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.51.2,<4.0a0 + - libsqlite >=3.50.4,<4.0a0 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.5,<4.0a0 + - openssl >=3.5.4,<4.0a0 - python_abi 3.13.* *_cp313 - tk >=8.6.13,<8.7.0a0 - tzdata @@ -8700,8 +4497,8 @@ packages: - vc14_runtime >=14.44.35208 license: Python-2.0 purls: [] - size: 16535316 - timestamp: 1770270322707 + size: 16613183 + timestamp: 1761175050438 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 @@ -8710,36 +4507,17 @@ packages: requires_dist: - six>=1.5 requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' -- 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 +- pypi: https://files.pythonhosted.org/packages/d8/f0/c5aa0a69fd9326f013110653543f36ece4913c17921f3e1dbd78e1b423ee/python_engineio-4.12.3-py3-none-any.whl name: python-engineio - version: 4.13.1 - sha256: f32ad10589859c11053ad7d9bb3c9695cdf862113bfb0d20bc4d890198287399 + version: 4.12.3 + sha256: 7c099abb2a27ea7ab429c04da86ab2d82698cdd6c52406cb73766fe454feb7e1 requires_dist: - simple-websocket>=0.10.0 - requests>=2.21.0 ; extra == 'client' - websocket-client>=0.54.0 ; extra == 'client' - - aiohttp>=3.11 ; extra == 'asyncio-client' - - tox ; extra == 'dev' + - aiohttp>=3.4 ; extra == 'asyncio-client' - sphinx ; extra == 'docs' - - furo ; extra == 'docs' - requires_python: '>=3.8' + requires_python: '>=3.6' - 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 @@ -8766,10 +4544,10 @@ packages: - mkdocs-literate-nav ; extra == 'dev' - mike ; extra == 'dev' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/07/c7/deb8c5e604404dbf10a3808a858946ca3547692ff6316b698945bb72177e/python_socketio-5.16.1-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/cd/fa/1ef2f8537272a2f383d72b9301c3ef66a49710b3bb7dcb2bd138cf2920d1/python_socketio-5.15.0-py3-none-any.whl name: python-socketio - version: 5.16.1 - sha256: a3eb1702e92aa2f2b5d3ba00261b61f062cce51f1cfb6900bf3ab4d1934d2d35 + version: 5.15.0 + sha256: e93363102f4da6d8e7a8872bf4908b866c40f070e716aa27132891e643e2687c requires_dist: - bidict>=0.21.0 - python-engineio>=4.11.0 @@ -8778,7 +4556,6 @@ 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 @@ -8791,39 +4568,15 @@ packages: purls: [] size: 7002 timestamp: 1752805902938 -- 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 +- 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 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.3 - sha256: 9c91dbb026050c77bdcef964e63a4f10f01a639113c4d3658332614544c467ab + version: 3.0.2 + sha256: 18f78b81e4cfee6aabe7ea8688441d30247b73e52cd9657138015c5f4ee13a51 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 @@ -8844,32 +4597,6 @@ 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 @@ -8877,13 +4604,6 @@ 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 @@ -8898,56 +4618,47 @@ packages: requires_dist: - cffi ; implementation_name == 'pypy' requires_python: '>=3.8' -- 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 +- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda + sha256: 2d6d0c026902561ed77cd646b5021aef2d4db22e57a5b0178dfc669231e06d2c + md5: 283b96675859b20a825f8fa30f311446 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 + - libgcc >=13 - ncurses >=6.5,<7.0a0 license: GPL-3.0-only license_family: GPL purls: [] - size: 345073 - timestamp: 1765813471974 -- conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda - sha256: 4614af680aa0920e82b953fece85a03007e0719c3399f13d7de64176874b80d5 - md5: eefd65452dfe7cce476a519bece46704 + size: 282480 + timestamp: 1740379431762 +- conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda + sha256: 53017e80453c4c1d97aaf78369040418dea14cf8f46a2fa999f31bd70b36c877 + md5: 342570f8e02f2f022147a7f841475784 depends: - - __osx >=10.13 - ncurses >=6.5,<7.0a0 license: GPL-3.0-only license_family: GPL purls: [] - size: 317819 - timestamp: 1765813692798 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - sha256: a77010528efb4b548ac2a4484eaf7e1c3907f2aec86123ed9c5212ae44502477 - md5: f8381319127120ce51e081dce4865cf4 + size: 256712 + timestamp: 1740379577668 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda + sha256: 7db04684d3904f6151eff8673270922d31da1eea7fa73254d01c437f49702e34 + md5: 63ef3f6e6d6d5c589e64f11263dc5676 depends: - - __osx >=11.0 - ncurses >=6.5,<7.0a0 license: GPL-3.0-only license_family: GPL purls: [] - size: 313930 - timestamp: 1765813902568 + 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' - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl name: referencing version: 0.37.0 @@ -8969,16 +4680,12 @@ 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/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/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/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl name: rfc3339-validator version: 0.1.4 @@ -8999,228 +4706,62 @@ packages: - lark>=1.2.2 - pytest>=8.3.5 ; extra == 'testing' requires_python: '>=3.9' -- 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 +- 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 name: rpds-py - version: 0.30.0 - sha256: 806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 + version: 0.29.0 + sha256: 6410e66f02803600edb0b1889541f4b5cc298a5ccda0ad789cc50ef23b54813e requires_python: '>=3.10' -- 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/b3/b3/0860cdd012291dc21272895ce107f1e98e335509ba986dd83d72658b82b9/rpds_py-0.29.0-cp313-cp313-macosx_11_0_arm64.whl name: rpds-py - version: 0.30.0 - sha256: 33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 + version: 0.29.0 + sha256: 521807963971a23996ddaf764c682b3e46459b3c58ccd79fefbe16718db43154 requires_python: '>=3.10' -- 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/b9/42/555b4ee17508beafac135c8b450816ace5a96194ce97fefc49d58e5652ea/rpds_py-0.29.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: rpds-py - version: 0.30.0 - sha256: a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 + version: 0.29.0 + sha256: de73e40ebc04dd5d9556f50180395322193a78ec247e637e741c1b954810f295 requires_python: '>=3.10' -- 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/fd/d9/c5de60d9d371bbb186c3e9bf75f4fc5665e11117a25a06a6b2e0afb7380e/rpds_py-0.29.0-cp313-cp313-macosx_10_12_x86_64.whl name: rpds-py - version: 0.30.0 - sha256: e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 + version: 0.29.0 + sha256: 1585648d0760b88292eecab5181f5651111a69d90eff35d6b78aa32998886a61 requires_python: '>=3.10' -- 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/13/ac/9b9fe63716af8bdfddfacd0882bc1586f29985d3b988b3c62ddce2e202c3/ruff-0.14.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: ruff - version: 0.15.4 - sha256: a4386ba2cd6c0f4ff75252845906acc7c7c8e1ac567b7bc3d373686ac8c222ba + version: 0.14.6 + sha256: 167843a6f78680746d7e226f255d920aeed5e4ad9c03258094a2d49d3028b105 requires_python: '>=3.7' -- 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/36/6a/ad66d0a3315d6327ed6b01f759d83df3c4d5f86c30462121024361137b6a/ruff-0.14.6-py3-none-macosx_10_12_x86_64.whl name: ruff - version: 0.15.4 - sha256: 5a1632c66672b8b4d3e1d1782859e98d6e0b4e70829530666644286600a33992 + version: 0.14.6 + sha256: 9f7539ea257aa4d07b7ce87aed580e485c40143f2473ff2f2b75aee003186004 requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/d0/a8/c688ef7e29983976820d18710f955751d9f4d4eb69df658af3d006e2ba3e/ruff-0.15.4-py3-none-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/a3/9d/dae6db96df28e0a15dea8e986ee393af70fc97fd57669808728080529c37/ruff-0.14.6-py3-none-macosx_11_0_arm64.whl name: ruff - version: 0.15.4 - sha256: 04196ad44f0df220c2ece5b0e959c2f37c777375ec744397d21d15b50a75264f + version: 0.14.6 + sha256: 7f6007e55b90a2a7e93083ba48a9f23c3158c433591c33ee2e99a49b889c6332 requires_python: '>=3.7' -- 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/fb/02/82240553b77fd1341f80ebb3eaae43ba011c7a91b4224a9f317d8e6591af/ruff-0.14.6-py3-none-win_amd64.whl name: ruff - version: 0.15.4 - sha256: 451a2e224151729b3b6c9ffb36aed9091b2996fe4bdbd11f47e27d8f2e8888ec + version: 0.14.6 + sha256: 390e6480c5e3659f8a4c8d6a0373027820419ac14fa0d2713bd8e6c3e125b8b9 requires_python: '>=3.7' -- 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.12.0 - sha256: aee5f585232e2a7a664f57bb9695164715271b74896704e7ee8a669dd7b06008 - 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/e5/22/75e119e0a200914f88f121cd956e1eb7f72c8ace4b63171f52ba0334d142/scipp-25.12.0-cp313-cp313-macosx_11_0_x86_64.whl +- pypi: https://files.pythonhosted.org/packages/64/7c/d8a343b0a622987335a1ac848084079c47c21e44fcc450f9c145b11a56f6/scipp-25.11.0-cp313-cp313-macosx_11_0_arm64.whl name: scipp - version: 25.12.0 - sha256: 27ebc37f3b7e20c9dca9cf1a0ac53c4ffaea31c02dfc8ba2b5aa008a252cbcba + version: 25.11.0 + sha256: 9b082fc7fd29919b4fee007f63db265176becb06c669a4b709feb741b76c612a requires_dist: - - numpy>=2 + - numpy>=1.20 - pytest ; extra == 'test' - matplotlib ; extra == 'test' - beautifulsoup4 ; extra == 'test' @@ -9241,12 +4782,12 @@ packages: - nodejs ; extra == 'all' - pythreejs ; extra == 'all' requires_python: '>=3.11' -- pypi: https://files.pythonhosted.org/packages/eb/d1/b3cd2733a96a36c54c36889b2cfdd0331c1e5b57fa1757485a22d0ec3142/scipp-25.12.0-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/71/f2/18d5be10ac890ce7490451eb55d41bf9d96e481751362a30ed1a8bc176fa/scipp-25.11.0-cp313-cp313-macosx_11_0_x86_64.whl name: scipp - version: 25.12.0 - sha256: 015db5035749750cf026db56fe537af10f159dc3cd0f51f0ea9f4ecc3a7a5da8 + version: 25.11.0 + sha256: fd7788e3ea3dd5334ed7fb53a249413469edc5d836ca5d68b1f271691cf11269 requires_dist: - - numpy>=2 + - numpy>=1.20 - pytest ; extra == 'test' - matplotlib ; extra == 'test' - beautifulsoup4 ; extra == 'test' @@ -9263,192 +4804,68 @@ packages: - 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/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' + - jupyter-nbextensions-configurator ; extra == 'all' + - nodejs ; extra == 'all' + - pythreejs ; extra == 'all' 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 +- 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 + name: scipp + version: 25.11.0 + sha256: 3e91c8093dc83d433a2e53708561228a06a7e34d8775a20118d391f5b891a6e6 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' + - 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' + 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 + 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' requires_python: '>=3.11' -- 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/21/f6/4bfb5695d8941e5c570a04d9fcd0d36bce7511b7d78e6e75c8f9791f82d0/scipy-1.16.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl name: scipy - version: 1.17.1 - sha256: 1f95b894f13729334fb990162e911c9e5dc1ab390c58aa6cbecb389c5b5e28ec + version: 1.16.3 + sha256: 7dc1360c06535ea6116a2220f760ae572db9f661aba2d88074fe30ec2aa1ff88 requires_dist: - - numpy>=1.26.4,<2.7 + - numpy>=1.25.2,<2.6 - pytest>=8.0.0 ; extra == 'test' - pytest-cov ; extra == 'test' - pytest-timeout ; extra == 'test' @@ -9477,22 +4894,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.12.0 ; extra == 'dev' + - ruff>=0.0.292 ; 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/ec/ae/db19f8ab842e9b724bf5dbb7db29302a91f1e55bc4d04b1025d6d605a2c5/scipy-1.17.1-cp313-cp313-macosx_12_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/44/13/7e63cfba8a7452eb756306aa2fd9b37a29a323b672b964b4fdeded9a3f21/scipy-1.16.3-cp313-cp313-macosx_12_0_arm64.whl name: scipy - version: 1.17.1 - sha256: 6fac755ca3d2c3edcb22f479fceaa241704111414831ddd3bc6056e18516892f + version: 1.16.3 + sha256: 16b8bc35a4cc24db80a0ec836a9286d0e31b2503cb2fd7ff7fb0e0374a97081d requires_dist: - - numpy>=1.26.4,<2.7 + - numpy>=1.25.2,<2.6 - pytest>=8.0.0 ; extra == 'test' - pytest-cov ; extra == 'test' - pytest-timeout ; extra == 'test' @@ -9521,22 +4938,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.12.0 ; extra == 'dev' + - ruff>=0.0.292 ; 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/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/72/f1/57e8327ab1508272029e27eeef34f2302ffc156b69e7e233e906c2a5c379/scipy-1.16.3-cp313-cp313-macosx_10_14_x86_64.whl name: scipy - version: 1.17.1 - sha256: 581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464 + version: 1.16.3 + sha256: d2ec56337675e61b312179a1ad124f5f570c00f920cc75e1000025451b88241c requires_dist: - - numpy>=1.26.4,<2.7 + - numpy>=1.25.2,<2.6 - pytest>=8.0.0 ; extra == 'test' - pytest-cov ; extra == 'test' - pytest-timeout ; extra == 'test' @@ -9565,22 +4982,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.12.0 ; extra == 'dev' + - ruff>=0.0.292 ; 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/f7/58/bccc2861b305abdd1b8663d6130c0b3d7cc22e8d86663edbc8401bfd40d4/scipy-1.17.1-cp311-cp311-macosx_12_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/cd/01/1204382461fcbfeb05b6161b594f4007e78b6eba9b375382f79153172b4d/scipy-1.16.3-cp313-cp313-win_amd64.whl name: scipy - version: 1.17.1 - sha256: e18f12c6b0bc5a592ed23d3f7b891f68fd7f8241d69b7883769eb5d5dfb52696 + version: 1.16.3 + sha256: 062246acacbe9f8210de8e751b16fc37458213f124bef161a5a02c7a39284304 requires_dist: - - numpy>=1.26.4,<2.7 + - numpy>=1.25.2,<2.6 - pytest>=8.0.0 ; extra == 'test' - pytest-cov ; extra == 'test' - pytest-timeout ; extra == 'test' @@ -9609,29 +5026,30 @@ 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.12.0 ; extra == 'dev' + - ruff>=0.0.292 ; 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/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl name: send2trash - 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 + 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 name: setuptools - version: 82.0.0 - sha256: 70b18734b607bd1da571d097d236cfcfacaf01de45717d59e6e04b96877532e0 + version: 80.9.0 + sha256: 062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 requires_dist: - pytest>=6,!=8.1.* ; extra == 'test' - virtualenv>=13.0.0 ; extra == 'test' @@ -9677,14 +5095,23 @@ packages: - more-itertools ; extra == 'core' - pytest-checkdocs>=2.4 ; extra == 'check' - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' - - ruff>=0.13.0 ; sys_platform != 'cygwin' and extra == 'check' + - ruff>=0.8.0 ; sys_platform != 'cygwin' and extra == 'check' - pytest-cov ; extra == 'cover' - pytest-enabler>=2.2 ; extra == 'enabler' - pytest-mypy ; extra == 'type' - - mypy==1.18.* ; extra == 'type' + - mypy==1.14.* ; 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 @@ -9702,37 +5129,213 @@ packages: version: 1.17.0 sha256: 4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' -- 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 +- 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 requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl +- 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 name: soupsieve - version: 2.8.3 - sha256: ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95 + 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/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' +- 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' + 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' 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 @@ -9747,13 +5350,11 @@ packages: - pygments ; extra == 'tests' - littleutils ; extra == 'tests' - cython ; extra == 'tests' -- 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/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/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl name: terminado version: 0.18.1 @@ -9782,119 +5383,110 @@ 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_h366c992_103.conda - sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac - md5: cffd3bdd58090148f4cfcd831f4b26ab +- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda + sha256: 1544760538a40bcd8ace2b1d8ebe3eb5807ac268641f8acdc18c69c5ebfeaf64 + md5: 86bc20552bf46075e3d92b67f089172d depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=14 + - libgcc >=13 - libzlib >=1.3.1,<2.0a0 constrains: - xorg-libx11 >=1.8.12,<2.0a0 license: TCL license_family: BSD purls: [] - size: 3301196 - timestamp: 1769460227866 -- conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda - sha256: 7f0d9c320288532873e2d8486c331ec6d87919c9028208d3f6ac91dc8f99a67b - md5: 6e6efb7463f8cef69dbcb4c2205bf60e + size: 3284905 + timestamp: 1763054914403 +- conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_3.conda + sha256: 0d0b6cef83fec41bc0eb4f3b761c4621b7adfb14378051a8177bd9bb73d26779 + md5: bd9f1de651dbd80b51281c694827f78f depends: - __osx >=10.13 - libzlib >=1.3.1,<2.0a0 license: TCL license_family: BSD purls: [] - size: 3282953 - timestamp: 1769460532442 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - sha256: 799cab4b6cde62f91f750149995d149bc9db525ec12595e8a1d91b9317f038b3 - md5: a9d86bc62f39b94c4661716624eb21b0 + size: 3262702 + timestamp: 1763055085507 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_3.conda + sha256: ad0c67cb03c163a109820dc9ecf77faf6ec7150e942d1e8bb13e5d39dc058ab7 + md5: a73d54a5abba6543cb2f0af1bfbd6851 depends: - __osx >=11.0 - libzlib >=1.3.1,<2.0a0 license: TCL license_family: BSD purls: [] - size: 3127137 - timestamp: 1769460817696 -- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda - sha256: 0e79810fae28f3b69fe7391b0d43f5474d6bd91d451d5f2bde02f55ae481d5e3 - md5: 0481bfd9814bf525bd4b3ee4b51494c4 + size: 3125484 + timestamp: 1763055028377 +- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_3.conda + sha256: 4581f4ffb432fefa1ac4f85c5682cc27014bcd66e7beaa0ee330e927a7858790 + md5: 7cb36e506a7dba4817970f8adb6396f9 depends: - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: TCL license_family: BSD purls: [] - 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 + 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 name: tornado - version: 6.5.4 - sha256: e5fb5e04efa54cf0baabdd10061eb4148e0be137166146fff835745f59ab9f7f + version: 6.5.2 + sha256: e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f requires_python: '>=3.9' -- 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/f2/b5/9b575a0ed3e50b00c40b08cbce82eb618229091d09f6d14bce80fc01cb0b/tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl name: tornado - version: 6.5.4 - sha256: d6241c1a16b1c9e4cc28148b1cda97dd1c6cb4fb7068ac1bedc610768dff0ba9 + version: 6.5.2 + sha256: 583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/d6/6d/c69be695a0a64fd37a97db12355a035a6d90f79067a3cf936ec2b1dc38cd/tornado-6.5.4-cp39-abi3-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/f6/48/6a7529df2c9cc12efd2e8f5dd219516184d703b34c06786809670df5b3bd/tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl name: tornado - version: 6.5.4 - sha256: fa07d31e0cd85c60713f2b995da613588aa03e1303d75705dca6af8babc18ddc + version: 6.5.2 + sha256: 2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6 requires_python: '>=3.9' -- 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/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 name: tornado - version: 6.5.4 - sha256: 2d50f63dda1d2cac3ae1fa23d254e16b5e38153758470e9956cbc3d813d40843 + version: 6.5.2 + sha256: e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108 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 @@ -9910,34 +5502,27 @@ packages: - pytest-mypy-testing ; extra == 'test' - pytest>=7.0,<8.2 ; extra == 'test' requires_python: '>=3.8' -- 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/49/f6/73c4aa003d1237ee9bea8a46f49dc38c45dfe95af4f0da7e60678d388011/trove_classifiers-2025.11.14.15-py3-none-any.whl name: trove-classifiers - version: 2026.1.14.14 - sha256: 1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d + version: 2025.11.14.15 + sha256: d1dac259c1e908939862e3331177931c6df0a37af2c1a8debcc603d9115fcdd9 - 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/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 +- pypi: https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl name: tzdata - version: '2025.3' - sha256: 06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 + version: '2025.2' + sha256: 1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8 requires_python: '>=2' -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c - md5: ad659d0a2b3e47e38d829aa8cad2d610 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + sha256: 5aaa366385d716557e365f0a4e9c3fca43ba196872abbbe3d56bb610d131e192 + md5: 4222072737ccff51314b5ece9c7d6f5a license: LicenseRef-Public-Domain purls: [] - size: 119135 - timestamp: 1767016325805 + size: 122968 + timestamp: 1742727099393 - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 md5: 71b24316859acd00bdb8b38f5e2ce328 @@ -9963,10 +5548,6 @@ 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 @@ -9993,144 +5574,89 @@ packages: - flake8-use-fstring ; extra == 'dev' - pep8-naming ; extra == 'dev' requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl name: urllib3 - version: 2.6.3 - sha256: bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 + version: 2.5.0 + sha256: e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc requires_dist: - - brotli>=1.2.0 ; platform_python_implementation == 'CPython' and extra == 'brotli' - - brotlicffi>=1.2.0.0 ; platform_python_implementation != 'CPython' and extra == 'brotli' + - brotli>=1.0.9 ; platform_python_implementation == 'CPython' and extra == 'brotli' + - brotlicffi>=0.8.0 ; platform_python_implementation != 'CPython' and extra == 'brotli' - h2>=4,<5 ; extra == 'h2' - pysocks>=1.5.6,!=1.5.7,<2.0 ; extra == 'socks' - - backports-zstd>=1.0.0 ; python_full_version < '3.14' and extra == 'zstd' + - zstandard>=0.18.0 ; extra == 'zstd' requires_python: '>=3.9' -- 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 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_32.conda + sha256: 82250af59af9ff3c6a635dd4c4764c631d854feb334d6747d356d949af44d7cf + md5: ef02bbe151253a72b8eda264a935db66 depends: - - vc14_runtime >=14.44.35208 + - vc14_runtime >=14.42.34433 track_features: - vc14 license: BSD-3-Clause license_family: BSD purls: [] - 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 + 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 depends: - ucrt >=10.0.20348.0 - - vcomp14 14.44.35208 h818238b_34 + - vcomp14 14.44.35208 h818238b_32 constrains: - - vs2015_runtime 14.44.35208.* *_34 + - vs2015_runtime 14.44.35208.* *_32 license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime license_family: Proprietary purls: [] - size: 683233 - timestamp: 1767320219644 -- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - sha256: 878d5d10318b119bd98ed3ed874bd467acbe21996e1d81597a1dbf8030ea0ce6 - md5: 242d9f25d2ae60c76b38a5e42858e51d + size: 682706 + timestamp: 1760418629729 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda + sha256: f3790c88fbbdc55874f41de81a4237b1b91eab75e05d0e58661518ff04d2a8a1 + md5: 58f67b437acbf2764317ba273d731f1d depends: - ucrt >=10.0.20348.0 constrains: - - vs2015_runtime 14.44.35208.* *_34 + - vs2015_runtime 14.44.35208.* *_32 license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime license_family: Proprietary purls: [] - 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 + size: 114846 + timestamp: 1760418593847 +- pypi: https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl name: virtualenv - version: 21.1.0 - sha256: 164f5e14c5587d170cf98e60378eb91ea35bf037be313811905d3a24ea33cc07 + version: 20.35.4 + sha256: c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b requires_dist: - distlib>=0.3.7,<1 - - filelock>=3.24.2,<4 ; python_full_version >= '3.10' - - filelock>=3.16.1,<=3.19.1 ; python_full_version < '3.10' + - filelock>=3.12.2,<4 - 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/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 +- pypi: https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl name: wcwidth - version: 0.6.0 - sha256: 1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad - requires_python: '>=3.8' + version: 0.2.14 + sha256: a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1 + requires_python: '>=3.6' - pypi: https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl name: webcolors version: 25.10.0 @@ -10153,11 +5679,6 @@ 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 @@ -10165,132 +5686,39 @@ packages: requires_dist: - h11>=0.16.0,<1 requires_python: '>=3.10' -- 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.23.0 - sha256: cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c - requires_dist: - - idna>=2.0 - - multidict>=4.0 - - propcache>=0.2.1 - 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.23.0 - sha256: 34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4 - requires_dist: - - idna>=2.0 - - multidict>=4.0 - - propcache>=0.2.1 - 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.23.0 - sha256: 4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5 - requires_dist: - - idna>=2.0 - - multidict>=4.0 - - propcache>=0.2.1 - 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 +- pypi: https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl name: yarl - version: 1.23.0 - sha256: bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46 + version: 1.22.0 + sha256: 01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a 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 + 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 name: yarl - version: 1.23.0 - sha256: 99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598 + version: 1.22.0 + sha256: bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b 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 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl name: yarl - version: 1.23.0 - sha256: 7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b + version: 1.22.0 + sha256: 22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c 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 + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl name: yarl - version: 1.23.0 - sha256: dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432 + version: 1.22.0 + sha256: 47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d 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 5bc43ea6..a7a8897b 100644 --- a/pixi.toml +++ b/pixi.toml @@ -1,259 +1,54 @@ -####################### -# 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] - -# 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 +name = "easyscience" +channels = ["conda-forge"] +platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"] [dependencies] -nodejs = '*' # Required for Prettier (non-Python formatting) -#gsl = '*' # GNU Scientific Library; required for pdffit2 +python = ">=3.11,<3.14" -[pypi-dependencies] # == [feature.default.pypi-dependencies] -#pip = '*' # Native package installer -easyscience = { path = ".", editable = true, extras = ['dev'] } +[feature.dev.pypi-dependencies] +# Development dependencies +easyscience = { path = ".", extras = ["dev"], editable = true } -# Specific features: Set specific Python versions +[feature.docs.pypi-dependencies] +# Documentation dependencies +easyscience = { path = ".", extras = ["docs"], editable = true } -[feature.py-min.dependencies] -python = '3.11.*' -[feature.py-max.dependencies] -python = '3.13.*' - -############## -# ENVIRONMENTS -############## +[feature.build.pypi-dependencies] +# build dependencies +easyscience = { path = ".", extras = ["build"], editable = true } [environments] - -# 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 -####### +# Default environment with basic build setup +default = ["build"] +# Development environment with build, dev, and docs features +dev = ["build", "dev", "docs"] [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" -################## -# 🧪 Testing Tasks -################## - -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' - -test = { depends-on = ['unit-tests'] } - -########### -# ✔️ Checks -########### - -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 quality tasks +lint-check = "ruff check ." +lint = "ruff check . --fix" +format-check = "ruff format . --check" +format = "ruff format ." -#################### -# 🧮 Code Complexity -#################### +# Build tasks +build = "python -m build" +clean = "rm -rf dist/ build/ *.egg-info/" +update-lock = "pixi update" -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/' +# Tox tasks +tox = "tox" -############# -# 📊 Coverage -############# +# Documentation tasks +docs-build = "sphinx-build -b html docs/src docs/_build/html" +docs-clean = "rm -rf docs/_build/" -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', -] } +[pypi-dependencies] # == [feature.default.pypi-dependencies] +# Editable install of the package itself +easyscience = { path = ".", editable = true } -########################## -# 🔗 Main Package Shortcut -########################## -easyscience = 'python -m easyscience' diff --git a/prettierrc.toml b/prettierrc.toml deleted file mode 100644 index b98c86eb..00000000 --- a/prettierrc.toml +++ /dev/null @@ -1,22 +0,0 @@ -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 c4cba0c2..3cdb977c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,243 +1,162 @@ -############################### -# Configuration for the project -############################### +[build-system] +requires = [ + "hatchling<=1.21.0", + "setuptools-git-versioning", +] +build-backend = "hatchling.build" + +[tool.setuptools-git-versioning] +enabled = true [project] -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'] +name = "easyscience" +dynamic = ["version"] +description = "Generic logic for easyScience libraries" +readme = "README.md" +authors = [{name = "EasyScience contributors"}] +license = { file = "LICENSE" } classifiers = [ - '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', + "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" ] -requires-python = '>=3.11' +requires-python = ">=3.11" dependencies = [ - '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 + "asteval", + "bumps", + "DFO-LS", + "lmfit", + "numpy", + "uncertainties", + "scipp" ] [project.optional-dependencies] +build = [ + "hatchling <= 1.21.0", + "setuptools-git-versioning", + "build" +] dev = [ - '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 + "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" ] [project.urls] -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' - -############################ -# Build system configuration -############################ +homepage = "https://github.com/EasyScience/EasyScience" +documentation = "https://easyscience.github.io/EasyScience/" -# Build system 'hatch' -- Python project manager -# https://hatch.pypa.io/ - -# Versioning system 'versioningit' -- Versioning from git tags -# https://versioningit.readthedocs.io/ - -[build-system] -build-backend = 'hatchling.build' -requires = ['hatchling', 'versioningit'] - -############################# -# Configuration for hatchling -############################# - -[tool.hatch.build.targets.wheel] -packages = ['src/easyscience'] -exclude = ['src/easyscience/legacy'] +[tool.hatch.version] +path = "src/easyscience/__version__.py" [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] -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.hatch.build.targets.sdist] +packages = ["src"] -[tool.pytest.ini_options] -addopts = '--import-mode=importlib' -markers = ['fast: mark test as fast (should be run on every push)'] -testpaths = ['tests'] +[tool.hatch.build.targets.wheel] +packages = ["src/easyscience"] +exclude = ["src/easyscience/legacy"] -######################## -# Configuration for ruff -######################## +[tool.coverage.run] +source = ["src/easyscience"] -# 'ruff' -- Python linter and code formatter -# https://docs.astral.sh/ruff/rules/ +[tool.github.info] +organization = 'EasyScience' +repo = "easyscience" [tool.ruff] -exclude = ['legacy', 'tests'] -indent-width = 4 -line-length = 99 -preview = true # Enable new rules that are not yet stable, like DOC +line-length = 127 +exclude = [ + "docs", + "examples_old", + "tests" +] [tool.ruff.format] -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) +quote-style = "single" + +[tool.ruff.per-file-ignores] +# allow asserts in test files +"*test_*.py" = ["S101"] -# https://docs.astral.sh/ruff/rules/ [tool.ruff.lint] +ignore-init-module-imports = true select = [ - # '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) + # 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", ] -[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.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 +[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 +""" diff --git a/resources/images/ec_logo.svg b/resources/images/ec_logo.svg new file mode 100644 index 00000000..25ee716f --- /dev/null +++ b/resources/images/ec_logo.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/images/ec_logo_single.svg b/resources/images/ec_logo_single.svg new file mode 100644 index 00000000..d6f33918 --- /dev/null +++ b/resources/images/ec_logo_single.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + diff --git a/resources/images/ec_logo_wfont.svg b/resources/images/ec_logo_wfont.svg new file mode 100644 index 00000000..046d884a --- /dev/null +++ b/resources/images/ec_logo_wfont.svg @@ -0,0 +1,38 @@ + + + + + + + easycore + + + + + + + + \ No newline at end of file diff --git a/resources/scripts/generate_html.py b/resources/scripts/generate_html.py new file mode 100644 index 00000000..8f1a4cc6 --- /dev/null +++ b/resources/scripts/generate_html.py @@ -0,0 +1,28 @@ +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 167e98e0..e3d4b084 100644 --- a/src/easyscience/__init__.py +++ b/src/easyscience/__init__.py @@ -1,8 +1,3 @@ -# 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 @@ -11,14 +6,13 @@ 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 new file mode 100644 index 00000000..04188a16 --- /dev/null +++ b/src/easyscience/__version__.py @@ -0,0 +1 @@ +__version__ = '2.2.0' diff --git a/src/easyscience/base_classes/__init__.py b/src/easyscience/base_classes/__init__.py index b5dc0418..4fc8702b 100644 --- a/src/easyscience/base_classes/__init__.py +++ b/src/easyscience/base_classes/__init__.py @@ -1,11 +1,9 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - from .based_base import BasedBase from .collection_base import CollectionBase +from .collection_base_easylist import CollectionBase as CollectionBaseEasyList from .easy_list import EasyList from .model_base import ModelBase from .new_base import NewBase from .obj_base import ObjBase -__all__ = [BasedBase, CollectionBase, ObjBase, ModelBase, NewBase, EasyList] +__all__ = [BasedBase, CollectionBase, CollectionBaseEasyList, ObjBase, ModelBase, NewBase, EasyList] diff --git a/src/easyscience/base_classes/based_base.py b/src/easyscience/base_classes/based_base.py index 1e5ac567..a2427c7f 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 @@ -71,11 +63,9 @@ 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 @@ -83,7 +73,8 @@ 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 """ @@ -91,7 +82,8 @@ 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 @@ -100,32 +92,34 @@ 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) @@ -137,16 +131,17 @@ 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. """ @@ -159,7 +154,8 @@ 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. """ @@ -172,8 +168,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. """ @@ -187,11 +183,10 @@ 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) @@ -203,14 +198,12 @@ 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 3328abc5..0a4e8272 100644 --- a/src/easyscience/base_classes/collection_base.py +++ b/src/easyscience/base_classes/collection_base.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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,7 +119,8 @@ 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] @@ -128,9 +129,7 @@ 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): @@ -154,7 +153,8 @@ 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,12 +178,11 @@ 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: @@ -196,7 +195,8 @@ 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,7 +204,8 @@ 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 @@ -219,14 +220,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()) @@ -238,10 +239,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/collection_base_easylist.py b/src/easyscience/base_classes/collection_base_easylist.py new file mode 100644 index 00000000..2256135b --- /dev/null +++ b/src/easyscience/base_classes/collection_base_easylist.py @@ -0,0 +1,483 @@ +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project str: + """Human-readable name of the collection.""" + return self._name + + @name.setter + def name(self, new_name: str) -> None: + """Set the collection name and sync *display_name*.""" + if not isinstance(new_name, str): + raise TypeError('Name must be a string') + self._name = new_name + self.display_name = new_name + + # --- Minimal overrides (compatibility shims) --- + + def __getitem__(self, idx: int | slice | str) -> Any: + """Retrieve items by integer index, slice, unique-name key, or display name. + + String lookup first tries the EasyList key (unique_name), then falls + back to matching on the item's *name* attribute. If multiple items + share the same name a new ``CollectionBase`` containing all matches is + returned. + """ + if isinstance(idx, bool): + raise TypeError('Boolean indexing is not supported at the moment') + if isinstance(idx, slice): + return self._clone_with_items(self._data[idx]) + if isinstance(idx, str): + try: + return super().__getitem__(idx) + except KeyError: + pass + name_matches = [item for item in self._data if getattr(item, 'name', None) == idx] + if len(name_matches) == 1: + return name_matches[0] + if len(name_matches) > 1: + return self._clone_with_items(name_matches) + raise KeyError(f'No item with key or name "{idx}" found') + return super().__getitem__(idx) + + def __setitem__(self, idx: int | slice, value: Any) -> None: + """Set an item by index. + + When *value* is a plain number and the existing item has a ``value`` + attribute, the number is assigned to ``item.value`` (in-place update). + Otherwise the item is replaced via the EasyList, which + enforces type validation. + """ + if isinstance(idx, int) and isinstance(value, Number): + item = self[idx] + if not hasattr(item, 'value'): + raise NotImplementedError('At the moment only numerical values or EasyScience objects can be set.') + item.value = value + return + try: + super().__setitem__(idx, value) + except TypeError as exc: + raise NotImplementedError('At the moment only numerical values or EasyScience objects can be set.') from exc + + def insert(self, index: int, value: Any) -> None: + """Insert *value* before *index*, validating it against protected types.""" + try: + super().insert(index, value) + except TypeError as exc: + raise AttributeError('Only EasyScience objects can be put into an EasyScience group') from exc + + def __repr__(self) -> str: + return f'{self.__class__.__name__} `{self.name}` of length {len(self)}' + + def sort(self, key=None, reverse: bool = False, mapping=None) -> None: + """Sort items in place. + + :param key: Single-argument function used to extract a comparison key. + :param reverse: If ``True``, sort in descending order. + :param mapping: Deprecated alias for *key*. + """ + if mapping is not None: + if key is not None: + raise TypeError('Use either key or mapping, not both') + warnings.warn('sort(mapping=...) is deprecated; use sort(key=...) instead', DeprecationWarning) + key = mapping + super().sort(key=key, reverse=reverse) + + # --- Parameter/variable aggregation --- + + def get_all_variables(self) -> list[DescriptorBase]: + """Return all descriptors in this collection, recursing into nested items.""" + variables: list[DescriptorBase] = [] + for item in self._data: + if isinstance(item, DescriptorBase): + variables.append(item) + elif hasattr(item, 'get_all_variables'): + variables.extend(item.get_all_variables()) + return variables + + def get_all_parameters(self) -> list[Parameter]: + """Return all parameters in this collection, recursing into nested items. + + Each parameter appears at most once (deduplicated by identity). + """ + parameters: list[Parameter] = [] + seen = set() + for item in self._data: + if isinstance(item, Parameter): + parameters.append(item) + seen.add(id(item)) + continue + if hasattr(item, 'get_all_parameters'): + for parameter in item.get_all_parameters(): + if id(parameter) not in seen: + parameters.append(parameter) + seen.add(id(parameter)) + continue + if hasattr(item, 'get_parameters'): + for parameter in item.get_parameters(): + if id(parameter) not in seen: + parameters.append(parameter) + seen.add(id(parameter)) + continue + if hasattr(item, 'get_all_variables'): + for variable in item.get_all_variables(): + if isinstance(variable, Parameter) and id(variable) not in seen: + parameters.append(variable) + seen.add(id(variable)) + return parameters + + def get_parameters(self) -> list[Parameter]: + """Alias for :meth:`get_all_parameters`.""" + return self.get_all_parameters() + + def get_fittable_parameters(self) -> list[Parameter]: + """Return all independent (fittable) parameters.""" + return [parameter for parameter in self.get_all_parameters() if parameter.independent] + + def get_free_parameters(self) -> list[Parameter]: + """Return all fittable parameters that are not fixed.""" + return [parameter for parameter in self.get_fittable_parameters() if not parameter.fixed] + + def get_fit_parameters(self) -> list[Parameter]: + """Legacy alias for :meth:`get_free_parameters`.""" + return self.get_free_parameters() + + @property + def data(self) -> tuple[Any, ...]: + """Read-only snapshot of the collection items as a tuple.""" + return tuple(self._data) + + # --- Serialization --- + + def as_dict(self, skip: Optional[list[str]] = None) -> dict[str, Any]: + """Legacy. Serialize to a dict, always excluding ``unique_name``.""" + if skip is None: + skip = [] + if 'unique_name' not in skip: + skip = [*skip, 'unique_name'] + return self.to_dict(skip=skip) + + def encode(self, skip: Optional[list[str]] = None, encoder=None, **kwargs: Any) -> Any: + """Legacy. Encode the collection using the given encoder (default: ``SerializerDict``).""" + if encoder is None: + encoder = SerializerDict + return encoder().encode(self, skip=skip, **kwargs) + + @classmethod + def decode(cls, obj: Any, decoder=None) -> Any: + """Reconstruct a ``CollectionBase`` from a previously encoded object.""" + if decoder is None or decoder is SerializerDict: + return cls.from_dict(obj) + return decoder.decode(obj) + + def to_dict(self, skip: Optional[list[str]] = None) -> dict[str, Any]: + """Full serialization including ``@module``, ``@class``, and ``@version`` metadata. + + :param skip: List of attribute names to exclude from the output. + """ + if skip is None: + skip = [] + + try: + parent_module = self.__module__.split('.')[0] + module_version = import_module(parent_module).__version__ + except (AttributeError, ImportError): + module_version = None + + dict_repr: dict[str, Any] = { + '@module': self.__module__, + '@class': self.__class__.__name__, + '@version': module_version, + } + + if 'name' not in skip: + dict_repr['name'] = self.name + if 'display_name' not in skip and self._display_name is not None and self._display_name != self.name: + dict_repr['display_name'] = self._display_name + if 'unique_name' not in skip: + dict_repr['unique_name'] = self.unique_name + if self._protected_types != list(self._DEFAULT_PROTECTED_TYPES) and 'protected_types' not in skip: + dict_repr['protected_types'] = [ + {'@module': cls_.__module__, '@class': cls_.__name__} for cls_ in self._protected_types + ] + dict_repr['data'] = [self._serialize_item(item, skip=skip) for item in self._data] + return dict_repr + + @classmethod + def from_dict(cls, obj_dict: dict[str, Any]) -> CollectionBase: + """Reconstruct a ``CollectionBase`` from a dict produced by :meth:`to_dict`. + + :param obj_dict: Dictionary containing ``@module``, ``@class``, and ``data`` keys. + :raises ValueError: If the dictionary structure or class name is invalid. + """ + if not isinstance(obj_dict, dict) or '@class' not in obj_dict or '@module' not in obj_dict: + raise ValueError('Input must be a dictionary representing an EasyScience CollectionBase object.') + accepted_names = {base.__name__ for base in cls.__mro__ if issubclass(base, CollectionBase)} + if obj_dict['@class'] not in accepted_names: + raise ValueError(f'Class name in dictionary does not match the expected class: {cls.__name__}.') + + temp_dict = copy.deepcopy(obj_dict) + protected_types = temp_dict.pop('protected_types', None) + if protected_types is not None: + protected_types = cls._deserialize_protected_types(protected_types) + + raw_data = temp_dict.pop('data', []) + kwargs = SerializerBase.deserialize_dict(temp_dict) + data = [cls._deserialize_item(item) for item in raw_data] + name = kwargs.pop('name', None) + kwargs.pop('unique_name', None) + return cls(*data, name=name, protected_types=protected_types, **kwargs) + + def _convert_to_dict( + self, + in_dict: dict[str, Any], + encoder: Any, + skip: Optional[list[str]] = None, + **kwargs: Any, + ) -> dict[str, Any]: + """Legacy. Hook used by ``SerializerBase`` to populate *in_dict* with collection data.""" + if skip is None: + skip = [] + if 'name' not in skip: + in_dict['name'] = self.name + if self._display_name is not None and self._display_name != self.name and 'display_name' not in skip: + in_dict['display_name'] = self._display_name + in_dict['data'] = [encoder._convert_to_dict(item, skip=skip, **kwargs) for item in self._data] + return in_dict + + @staticmethod + def _deserialize_protected_types(protected_types: list[dict[str, str]]) -> list[type]: + """Resolve serialized ``{@module, @class}`` dicts back to live type objects.""" + deserialized_types: list[type] = [] + for type_dict in protected_types: + if '@module' not in type_dict or '@class' not in type_dict: + raise ValueError('Each protected type must contain @module and @class keys') + module = __import__(type_dict['@module'], globals(), locals(), [type_dict['@class']], 0) + deserialized_types.append(getattr(module, type_dict['@class'])) + return deserialized_types + + def _clone_with_items(self, items: Iterable[Any]) -> CollectionBase: + """Create a shallow copy of this collection containing the given *items*.""" + return self.__class__( + *list(items), + name=self.name, + protected_types=list(self._protected_types), + display_name=self._display_name, + ) + + # --- Compatibility surface --- + + def __dir__(self) -> Iterable[str]: + # Names that exist on the class but should not be shown to users. + # These are internal/new-API names + hidden = { + 'display_name', + 'get_all_parameters', + 'get_all_variables', + 'get_fittable_parameters', + 'get_free_parameters', + 'to_dict', + } + # Names that the old BasedBase/BaseObj API exposed and that + # downstream code may rely on for introspection + legacy = { + 'append', + 'as_dict', + 'clear', + 'constraints', + 'count', + 'data', + 'decode', + 'encode', + 'extend', + 'from_dict', + 'generate_bindings', + 'get_fit_parameters', + 'get_parameters', + 'index', + 'insert', + 'interface', + 'name', + 'pop', + 'remove', + 'reverse', + 'sort', + 'switch_interface', + 'unique_name', + 'user_data', + } + public_names = {name for name in dir(self.__class__) if not name.startswith('_')} + return sorted((public_names | legacy) - hidden) + + @property + def constraints(self) -> list[Any]: + """Compatibility stub — always returns an empty list.""" + return [] + + def generate_bindings(self) -> None: + """Compatibility stub — requires ``interface`` to be set.""" + if self.interface is None: + raise AttributeError('Interface error for generating bindings. `interface` has to be set.') + + def switch_interface(self, new_interface_name: str) -> None: + """Compatibility stub — requires ``interface`` to be set.""" + if self.interface is None: + raise AttributeError('Interface error for generating bindings. `interface` has to be set.') + + # --- Internal helpers --- + + def _collect_items( + self, + items: tuple[Any, ...], + data: Optional[Iterable[Any]] = None, + ) -> list[Any]: + """Merge positional *items* and *data* into a flat list. + + Lists inside *items* are flattened one level. + """ + collected: list[Any] = [] + for item in items: + if isinstance(item, list): + collected.extend(item) + else: + collected.append(item) + if data is not None: + collected.extend(data) + return collected + + def _normalize_protected_types(self, protected_types: type | Iterable[type] | None) -> list[type]: + """Coerce *protected_types* into a list, falling back to the class default.""" + if protected_types is None: + return list(self._DEFAULT_PROTECTED_TYPES) + if isinstance(protected_types, type): + return [protected_types] + if isinstance(protected_types, Iterable): + normalized = list(protected_types) + if all(isinstance(item, type) for item in normalized): + return normalized + raise TypeError('protected_types must be a type or an iterable of types') + + def _serialize_item(self, item: Any, skip: Optional[list[str]] = None) -> dict[str, Any]: + """Serialize a single item via its ``to_dict`` or ``as_dict`` method.""" + if hasattr(item, 'to_dict'): + return item.to_dict() + if hasattr(item, 'as_dict'): + return item.as_dict(skip=skip) + raise TypeError(f'Unable to serialize item of type {type(item)}') + + @staticmethod + def _deserialize_item(item: Any) -> Any: + """Deserialize a single item dict back into an EasyScience object.""" + if not SerializerBase._is_serialized_easyscience_object(item): + return SerializerBase._deserialize_value(item) + + normalized_item = copy.deepcopy(item) + normalized_item.pop('unique_name', None) + return SerializerBase._deserialize_value(normalized_item) + + def _validate_item(self, item: Any) -> None: + """Raise ``TypeError`` if *item* is not an instance of a protected type.""" + if not isinstance(item, tuple(self._protected_types)): + raise TypeError(f'Items must be one of {self._protected_types}, got {type(item)}') diff --git a/src/easyscience/base_classes/easy_list.py b/src/easyscience/base_classes/easy_list.py index 39f04eaa..6af761e6 100644 --- a/src/easyscience/base_classes/easy_list.py +++ b/src/easyscience/base_classes/easy_list.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project '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 @@ -104,10 +101,9 @@ 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 @@ -116,9 +112,7 @@ def __setitem__( 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): @@ -127,25 +121,20 @@ def __setitem__( 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 """ @@ -165,7 +154,8 @@ 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 @@ -175,15 +165,13 @@ 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 @@ -194,9 +182,7 @@ 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): @@ -207,7 +193,8 @@ 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 @@ -225,7 +212,8 @@ 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 @@ -243,31 +231,29 @@ 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: @@ -281,9 +267,7 @@ 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' @@ -294,6 +278,4 @@ 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 419492c9..3a6a4061 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 @@ -44,7 +43,8 @@ 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,39 +58,40 @@ 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 @@ -115,6 +116,4 @@ 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 778e9ba9..604233bd 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 @@ -63,11 +58,9 @@ 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 @@ -76,7 +69,8 @@ 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. """ @@ -88,7 +82,8 @@ 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. """ @@ -97,13 +92,11 @@ 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: @@ -116,8 +109,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 @@ -128,16 +121,13 @@ 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 8576b67b..b42991f8 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,9 +133,7 @@ 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 54bad74a..f34b8b81 100644 --- a/src/easyscience/fitting/__init__.py +++ b/src/easyscience/fitting/__init__.py @@ -1,6 +1,3 @@ -# 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 0cfd262b..2d1fb717 100644 --- a/src/easyscience/fitting/available_minimizers.py +++ b/src/easyscience/fitting/available_minimizers.py @@ -1,6 +1,3 @@ -# SPDX-FileCopyrightText: 2024 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - import warnings from dataclasses import dataclass from enum import Enum @@ -16,11 +13,7 @@ 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: @@ -29,11 +22,7 @@ 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: @@ -42,11 +31,7 @@ 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 4104ddae..a3ca5d43 100644 --- a/src/easyscience/fitting/calculators/__init__.py +++ b/src/easyscience/fitting/calculators/__init__.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# 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 +# 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] @@ -96,7 +95,8 @@ 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,7 +117,8 @@ 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 @@ -127,8 +128,7 @@ 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,9 +139,8 @@ 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 @@ -190,7 +189,9 @@ 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 70524996..1ccacbe1 100644 --- a/src/easyscience/fitting/fitter.py +++ b/src/easyscience/fitting/fitter.py @@ -1,6 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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. @@ -56,10 +57,9 @@ 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,16 +79,13 @@ 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] @@ -97,7 +94,8 @@ 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 @@ -106,7 +104,8 @@ 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 """ @@ -114,7 +113,8 @@ 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,7 +122,8 @@ 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 """ @@ -130,24 +131,25 @@ 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 """ @@ -156,25 +158,26 @@ 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. @@ -194,13 +197,10 @@ 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,25 +211,20 @@ 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, @@ -255,8 +250,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 @@ -298,11 +293,9 @@ 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 ca70e748..5ca5ee06 100644 --- a/src/easyscience/fitting/minimizers/__init__.py +++ b/src/easyscience/fitting/minimizers/__init__.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2024 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# 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 .. import available_minimizers @@ -15,9 +12,7 @@ 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 b4539ac4..0b864657 100644 --- a/src/easyscience/fitting/minimizers/minimizer_base.py +++ b/src/easyscience/fitting/minimizers/minimizer_base.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project FitResults: - """Perform a fit using the engine. + """ + Perform a fit using the engine. :param x: points to be calculated at :type x: np.ndarray @@ -87,13 +89,10 @@ 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 @@ -130,11 +129,10 @@ 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 """ @@ -142,7 +140,8 @@ 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] @@ -151,7 +150,8 @@ 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,8 +179,9 @@ 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 """ @@ -196,8 +197,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 @@ -226,16 +227,14 @@ 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 @@ -251,9 +250,7 @@ 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 37f8873e..3315d2eb 100644 --- a/src/easyscience/fitting/minimizers/minimizer_bumps.py +++ b/src/easyscience/fitting/minimizers/minimizer_bumps.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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 @@ -95,10 +97,12 @@ 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) @@ -125,9 +129,7 @@ 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 @@ -156,11 +158,10 @@ 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] @@ -174,8 +175,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 @@ -191,9 +192,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). @@ -207,25 +208,19 @@ 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 @@ -250,7 +245,8 @@ def _set_parameter_fit_result( 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 a480c823..dacef618 100644 --- a/src/easyscience/fitting/minimizers/minimizer_dfo.py +++ b/src/easyscience/fitting/minimizers/minimizer_dfo.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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 @@ -82,10 +84,11 @@ 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) @@ -129,18 +132,22 @@ 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 @@ -169,12 +176,11 @@ 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 """ @@ -197,7 +203,8 @@ 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 @@ -235,8 +242,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 4a8104b2..2c63cea3 100644 --- a/src/easyscience/fitting/minimizers/minimizer_lmfit.py +++ b/src/easyscience/fitting/minimizers/minimizer_lmfit.py @@ -1,5 +1,7 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project FitResults: - """Perform a fit using the lmfit engine. + """ + Perform a fit using the lmfit engine. :param method: :type method: @@ -104,15 +106,16 @@ 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) @@ -162,9 +165,7 @@ 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: @@ -175,25 +176,22 @@ def _get_fit_kws( 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 @@ -211,8 +209,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 @@ -249,8 +247,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 76449a17..60ab00a6 100644 --- a/src/easyscience/fitting/minimizers/utils.py +++ b/src/easyscience/fitting/minimizers/utils.py @@ -1,12 +1,9 @@ -# 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 94e715c6..a30bdcec 100644 --- a/src/easyscience/fitting/multi_fitter.py +++ b/src/easyscience/fitting/multi_fitter.py @@ -1,6 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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. @@ -68,9 +65,8 @@ 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? @@ -79,17 +75,13 @@ 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) @@ -108,10 +100,12 @@ 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__ @@ -129,12 +123,8 @@ 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 c0934dde..2adc1bc2 100644 --- a/src/easyscience/global_object/__init__.py +++ b/src/easyscience/global_object/__init__.py @@ -1,6 +1,3 @@ -# 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 dbaa994d..63726d01 100644 --- a/src/easyscience/global_object/global_object.py +++ b/src/easyscience/global_object/global_object.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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 b1990ec8..867a21c4 100644 --- a/src/easyscience/global_object/hugger/__init__.py +++ b/src/easyscience/global_object/hugger/__init__.py @@ -1,3 +1,4 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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 2367d1fb..a18f913b 100644 --- a/src/easyscience/global_object/hugger/property.py +++ b/src/easyscience/global_object/hugger/property.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project str: @@ -176,9 +174,7 @@ 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) @@ -191,9 +187,7 @@ 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 0400d524..f4fa3a42 100644 --- a/src/easyscience/global_object/logger.py +++ b/src/easyscience/global_object/logger.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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 c9172c09..a9d0b576 100644 --- a/src/easyscience/global_object/map.py +++ b/src/easyscience/global_object/map.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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: @@ -103,7 +102,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 @@ -187,10 +186,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 @@ -222,7 +221,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): @@ -230,7 +229,8 @@ 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,7 +246,8 @@ 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] @@ -263,11 +264,9 @@ 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: @@ -292,7 +291,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 @@ -303,19 +302,14 @@ 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 bb1e173c..7317ec23 100644 --- a/src/easyscience/global_object/undo_redo.py +++ b/src/easyscience/global_object/undo_redo.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project None: self._obj = obj @@ -26,11 +29,15 @@ 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: @@ -61,9 +68,8 @@ 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): @@ -95,8 +101,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): @@ -143,7 +149,9 @@ 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) @@ -175,7 +183,9 @@ 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. @@ -210,13 +220,17 @@ 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() @@ -233,7 +247,9 @@ 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() @@ -251,8 +267,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') @@ -261,30 +277,38 @@ 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 @@ -292,7 +316,9 @@ 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 6a53db96..b21e648c 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 - +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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 @@ -53,8 +50,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 @@ -63,8 +60,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 @@ -76,7 +73,8 @@ 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 @@ -119,7 +117,9 @@ 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,9 +189,7 @@ 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'): @@ -225,11 +223,12 @@ 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): @@ -250,11 +249,7 @@ 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'): @@ -267,24 +262,20 @@ 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 @@ -310,21 +301,18 @@ 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 @@ -342,33 +330,24 @@ 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 02938a29..85da9961 100644 --- a/src/easyscience/io/serializer_component.py +++ b/src/easyscience/io/serializer_component.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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` @@ -45,12 +44,11 @@ def encode( @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 """ @@ -59,22 +57,20 @@ 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 8dc73a63..8fe423c1 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 73852c24..5a1770f5 100644 --- a/src/easyscience/job/__init__.py +++ b/src/easyscience/job/__init__.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause - +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause +# 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 __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( @@ -78,16 +75,13 @@ 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. """ @@ -102,18 +96,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(): @@ -125,8 +119,5 @@ 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 12a151e7..6464e52a 100644 --- a/src/easyscience/legacy/json.py +++ b/src/easyscience/legacy/json.py @@ -1,11 +1,12 @@ -# 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__, @@ -36,8 +37,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 @@ -56,15 +57,13 @@ 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:: @@ -93,12 +92,13 @@ 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,7 +109,8 @@ 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 1fed4b86..daddabee 100644 --- a/src/easyscience/legacy/legacy_core.py +++ b/src/easyscience/legacy/legacy_core.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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` @@ -55,12 +48,11 @@ def encode( @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 """ @@ -69,22 +61,20 @@ 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 @@ -92,14 +82,9 @@ 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` @@ -112,23 +97,20 @@ def encode_data( 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='.'): @@ -137,15 +119,9 @@ 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 7ec29950..e0898409 100644 --- a/src/easyscience/legacy/xml.py +++ b/src/easyscience/legacy/xml.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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 """ @@ -77,8 +74,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. @@ -92,7 +89,9 @@ 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] == '_': @@ -114,7 +113,9 @@ 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() @@ -136,8 +137,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 3fc7f778..a9aed973 100644 --- a/src/easyscience/models/__init__.py +++ b/src/easyscience/models/__init__.py @@ -1,4 +1,5 @@ -# SPDX-FileCopyrightText: 2024 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project = 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 554dc85e..462d95af 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 - +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause +# 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 .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 6bdf7f39..c00ccb01 100644 --- a/src/easyscience/variable/descriptor_any_type.py +++ b/src/easyscience/variable/descriptor_any_type.py @@ -1,6 +1,3 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - from __future__ import annotations import numbers @@ -18,11 +15,9 @@ 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__( @@ -35,7 +30,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 @@ -59,7 +54,8 @@ def __init__( @property def value(self) -> numbers.Number: - """Get the value. + """ + Get the value. :return: Value of self. """ @@ -68,7 +64,8 @@ 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. """ @@ -78,8 +75,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 aecc684a..9e9b8e6f 100644 --- a/src/easyscience/variable/descriptor_array.py +++ b/src/easyscience/variable/descriptor_array.py @@ -1,6 +1,3 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - from __future__ import annotations import numbers @@ -26,9 +23,8 @@ 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__( @@ -44,7 +40,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 @@ -76,17 +72,13 @@ 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: @@ -112,7 +104,8 @@ 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 @@ -132,8 +125,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. """ @@ -147,8 +140,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. """ @@ -157,12 +150,11 @@ 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.') @@ -177,7 +169,8 @@ 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. """ @@ -185,8 +178,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. """ @@ -198,15 +191,14 @@ 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. """ @@ -223,7 +215,8 @@ 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. """ @@ -232,19 +225,16 @@ 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.') @@ -257,11 +247,10 @@ 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 @@ -270,8 +259,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. """ @@ -293,7 +282,8 @@ 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 """ @@ -316,22 +306,21 @@ 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 @@ -366,10 +355,9 @@ 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 @@ -384,16 +372,13 @@ 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 @@ -407,14 +392,10 @@ 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: @@ -422,9 +403,7 @@ 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 @@ -439,9 +418,7 @@ 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): @@ -450,9 +427,7 @@ 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: @@ -476,9 +451,8 @@ 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. """ @@ -496,9 +470,7 @@ 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) @@ -508,59 +480,45 @@ 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 @@ -574,14 +532,12 @@ def __sub__( 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): @@ -593,44 +549,34 @@ 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 @@ -646,12 +592,9 @@ def __truediv__( 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)): @@ -666,13 +609,12 @@ def __rtruediv__( 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 @@ -698,26 +640,27 @@ 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) @@ -725,27 +668,25 @@ 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\ @@ -756,17 +697,14 @@ 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: @@ -779,9 +717,7 @@ 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) @@ -789,11 +725,7 @@ 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 @@ -801,23 +733,16 @@ 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) @@ -858,8 +783,8 @@ def sum( # 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 07b4aaa1..4bb54e4a 100644 --- a/src/easyscience/variable/descriptor_base.py +++ b/src/easyscience/variable/descriptor_base.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project str: - """Get the name of the object. + """ + Get the name of the object. :return: name of the object. """ @@ -96,7 +96,8 @@ 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. """ @@ -106,7 +107,8 @@ 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. """ @@ -118,7 +120,8 @@ 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. """ @@ -128,7 +131,8 @@ 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. """ @@ -136,7 +140,8 @@ 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. """ @@ -146,7 +151,8 @@ 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. """ @@ -154,7 +160,8 @@ 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. """ @@ -164,7 +171,8 @@ 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 """ @@ -172,11 +180,9 @@ 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 88135d61..72c41cd8 100644 --- a/src/easyscience/variable/descriptor_bool.py +++ b/src/easyscience/variable/descriptor_bool.py @@ -1,6 +1,3 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - from __future__ import annotations from typing import Any @@ -12,7 +9,9 @@ class DescriptorBool(DescriptorBase): - """A `Descriptor` for boolean values.""" + """ + A `Descriptor` for boolean values. + """ def __init__( self, @@ -40,7 +39,8 @@ def __init__( @property def value(self) -> bool: - """Get the value of self. + """ + Get the value of self. :return: Value of self """ @@ -49,7 +49,8 @@ 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 b526afbf..38b233f1 100644 --- a/src/easyscience/variable/descriptor_number.py +++ b/src/easyscience/variable/descriptor_number.py @@ -1,6 +1,3 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - from __future__ import annotations import numbers @@ -25,7 +22,8 @@ # 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 @@ -40,9 +38,8 @@ 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__( @@ -58,7 +55,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 @@ -85,9 +82,7 @@ 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: @@ -107,7 +102,8 @@ 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 @@ -118,13 +114,7 @@ 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.""" @@ -144,11 +134,9 @@ 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( @@ -163,8 +151,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. """ @@ -178,8 +166,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. """ @@ -189,8 +177,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 """ @@ -200,7 +188,8 @@ def value(self, value: numbers.Number) -> None: @property def unit(self) -> str: - """Get the unit. + """ + Get the unit. :return: Unit as a string. """ @@ -217,7 +206,8 @@ def unit(self, unit_str: str) -> None: @property def variance(self) -> float: - """Get the variance. + """ + Get the variance. :return: variance. """ @@ -227,7 +217,8 @@ 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 """ @@ -241,7 +232,8 @@ 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 """ @@ -253,7 +245,8 @@ 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 """ @@ -270,7 +263,8 @@ 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 """ @@ -293,9 +287,7 @@ 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 @@ -304,7 +296,8 @@ 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 """ @@ -319,9 +312,7 @@ 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: @@ -359,9 +350,7 @@ 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: @@ -391,9 +380,7 @@ 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: @@ -506,8 +493,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 c6e26f9c..17110166 100644 --- a/src/easyscience/variable/descriptor_str.py +++ b/src/easyscience/variable/descriptor_str.py @@ -1,6 +1,3 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - from __future__ import annotations from typing import Any @@ -12,7 +9,9 @@ class DescriptorStr(DescriptorBase): - """A `Descriptor` for string values.""" + """ + A `Descriptor` for string values. + """ def __init__( self, @@ -38,7 +37,8 @@ def __init__( @property def value(self) -> str: - """Get the value of self. + """ + Get the value of self. :return: Value of self with unit. """ @@ -47,7 +47,8 @@ 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 36e2c7a3..6ea8d1a6 100644 --- a/src/easyscience/variable/parameter.py +++ b/src/easyscience/variable/parameter.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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 @@ -130,20 +128,14 @@ 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 @@ -159,10 +151,8 @@ 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 @@ -171,14 +161,10 @@ 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 @@ -196,8 +182,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, @@ -218,11 +204,10 @@ 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' @@ -257,9 +242,7 @@ 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 @@ -300,9 +283,7 @@ 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( @@ -348,9 +329,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 """ @@ -368,7 +349,8 @@ def make_independent(self) -> None: @property def independent(self) -> bool: - """Is the parameter independent? + """ + Is the parameter independent? :return: True = independent, False = dependent """ @@ -382,7 +364,8 @@ 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. """ @@ -399,7 +382,8 @@ 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. """ @@ -410,13 +394,12 @@ 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. """ @@ -424,9 +407,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. """ @@ -440,7 +423,8 @@ 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. """ @@ -453,8 +437,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 """ @@ -476,39 +460,35 @@ 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 @@ -520,8 +500,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 @@ -529,16 +509,14 @@ 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.') @@ -547,16 +525,15 @@ 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 """ @@ -576,24 +553,19 @@ 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 """ @@ -613,24 +585,19 @@ 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 """ @@ -653,9 +620,7 @@ 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 @@ -667,9 +632,7 @@ 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 @@ -686,17 +649,13 @@ 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() @@ -712,11 +671,10 @@ 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) @@ -734,9 +692,7 @@ 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. ' @@ -746,8 +702,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 @@ -777,7 +733,9 @@ 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 = [] @@ -798,29 +756,19 @@ 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 @@ -831,25 +779,19 @@ 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 @@ -860,16 +802,12 @@ 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 @@ -880,9 +818,7 @@ 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 @@ -893,25 +829,19 @@ 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 @@ -919,22 +849,16 @@ 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): @@ -957,9 +881,7 @@ 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 @@ -968,20 +890,14 @@ 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] @@ -989,9 +905,7 @@ 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 @@ -1002,9 +916,7 @@ 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') @@ -1039,9 +951,7 @@ 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 @@ -1054,20 +964,14 @@ 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: @@ -1088,9 +992,7 @@ 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 @@ -1098,9 +1000,7 @@ 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: @@ -1117,9 +1017,7 @@ 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: @@ -1143,9 +1041,7 @@ 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 @@ -1153,9 +1049,7 @@ 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 @@ -1166,18 +1060,15 @@ 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 @@ -1192,9 +1083,7 @@ 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: @@ -1212,13 +1101,9 @@ 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 a4a21732..e6b7cbd6 100644 --- a/src/easyscience/variable/parameter_dependency_resolver.py +++ b/src/easyscience/variable/parameter_dependency_resolver.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2025 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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: @@ -79,15 +78,13 @@ 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 @@ -95,9 +92,7 @@ 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) @@ -131,19 +126,15 @@ 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 new file mode 100644 index 00000000..462d95af --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,3 @@ +# 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 new file mode 100644 index 00000000..1c8d2861 --- /dev/null +++ b/tests/coord_cython.pyx @@ -0,0 +1,273 @@ +# 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 new file mode 100644 index 00000000..b6784dff --- /dev/null +++ b/tests/coords.py @@ -0,0 +1,504 @@ +__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/__init__.py b/tests/integration_tests/fitting/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/integration/fitting/test_fitter.py b/tests/integration_tests/fitting/test_fitter.py similarity index 83% rename from tests/integration/fitting/test_fitter.py rename to tests/integration_tests/fitting/test_fitter.py index c6d130fd..d5c9b255 100644 --- a/tests/integration/fitting/test_fitter.py +++ b/tests/integration_tests/fitting/test_fitter.py @@ -1,15 +1,16 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project Parameter: @@ -83,12 +84,14 @@ 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 @@ -99,9 +102,8 @@ 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, @@ -125,7 +127,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) @@ -137,9 +139,8 @@ 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, @@ -159,11 +160,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()) } @@ -173,15 +174,14 @@ 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,12 +214,11 @@ 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), @@ -243,7 +242,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 @@ -251,8 +250,7 @@ def test_basic_tolerance(fit_engine, tolerance): assert sp_sin.offset.value != pytest.approx(ref_sin.offset.value, rel=1e-3) -@pytest.mark.fast -@pytest.mark.parametrize('fit_method', ['leastsq', 'powell', 'cobyla']) +@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) @@ -271,8 +269,7 @@ def test_lmfit_methods(fit_method): # @pytest.mark.xfail(reason="known bumps issue") -@pytest.mark.fast -@pytest.mark.parametrize('fit_method', ['newton', 'lm']) +@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) @@ -285,15 +282,14 @@ 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): @@ -307,22 +303,21 @@ 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, @@ -342,12 +337,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()) @@ -359,9 +354,8 @@ 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, @@ -381,12 +375,14 @@ 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()) @@ -395,12 +391,13 @@ 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, @@ -429,7 +426,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) @@ -440,7 +437,6 @@ 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) @@ -458,12 +454,13 @@ 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, @@ -504,7 +501,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 @@ -514,4 +511,6 @@ 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/fitting/test_multi_fitter.py b/tests/integration_tests/fitting/test_multi_fitter.py similarity index 61% rename from tests/integration/fitting/test_multi_fitter.py rename to tests/integration_tests/fitting/test_multi_fitter.py index 1cc5b395..fb2c7802 100644 --- a/tests/integration/fitting/test_multi_fitter.py +++ b/tests/integration_tests/fitting/test_multi_fitter.py @@ -1,13 +1,14 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# 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/tests/unit/fitting/__init__.py b/tests/unit/fitting/__init__.py deleted file mode 100644 index b1990ec8..00000000 --- a/tests/unit/fitting/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# 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 deleted file mode 100644 index b1990ec8..00000000 --- a/tests/unit/fitting/calculators/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - diff --git a/tests/unit/fitting/minimizers/__init__.py b/tests/unit/fitting/minimizers/__init__.py deleted file mode 100644 index b1990ec8..00000000 --- a/tests/unit/fitting/minimizers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - diff --git a/tests/unit/global_object/__init__.py b/tests/unit/global_object/__init__.py deleted file mode 100644 index b1990ec8..00000000 --- a/tests/unit/global_object/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - diff --git a/tests/unit/io/test_serializer_component.py b/tests/unit/io/test_serializer_component.py deleted file mode 100644 index c4e21f49..00000000 --- a/tests/unit/io/test_serializer_component.py +++ /dev/null @@ -1,96 +0,0 @@ -# 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/legacy/__init__.py b/tests/unit/legacy/__init__.py deleted file mode 100644 index b1990ec8..00000000 --- a/tests/unit/legacy/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# 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 deleted file mode 100644 index b1990ec8..00000000 --- a/tests/unit/legacy/test_dict.py +++ /dev/null @@ -1,3 +0,0 @@ -# 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 deleted file mode 100644 index b1990ec8..00000000 --- a/tests/unit/legacy/test_json.py +++ /dev/null @@ -1,3 +0,0 @@ -# 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 deleted file mode 100644 index b1990ec8..00000000 --- a/tests/unit/legacy/test_xml.py +++ /dev/null @@ -1,3 +0,0 @@ -# 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 deleted file mode 100644 index b1990ec8..00000000 --- a/tests/unit/models/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - diff --git a/tests/unit/variable/__init__.py b/tests/unit/variable/__init__.py deleted file mode 100644 index b1990ec8..00000000 --- a/tests/unit/variable/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - diff --git a/tests/unit/variable/test_descriptor_array.py b/tests/unit/variable/test_descriptor_array.py deleted file mode 100644 index 73bb0857..00000000 --- a/tests/unit/variable/test_descriptor_array.py +++ /dev/null @@ -1,1807 +0,0 @@ -# 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 deleted file mode 100644 index 24c342dc..00000000 --- a/tests/unit/variable/test_descriptor_base.py +++ /dev/null @@ -1,225 +0,0 @@ -# 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/__init__.py b/tests/unit_tests/__init__.py new file mode 100644 index 00000000..462d95af --- /dev/null +++ b/tests/unit_tests/__init__.py @@ -0,0 +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 + +# 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 +# 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 +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project -# SPDX-License-Identifier: BSD-3-Clause + +# 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 - -from unittest.mock import MagicMock +# 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 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 easyscience.fitting.minimizers.factory import factory - +from unittest.mock import MagicMock +import pytest class TestFactory: def pull_minminizer(self, minimizer: AvailableMinimizers) -> MinimizerBase: @@ -18,78 +12,36 @@ 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 @@ -107,4 +59,4 @@ def test_available_minimizers(): assert AvailableMinimizers.Bumps_lm assert AvailableMinimizers.DFO assert AvailableMinimizers.DFO_leastsq - assert len(AvailableMinimizers) == 12 + assert len(AvailableMinimizers) == 12 \ No newline at end of file diff --git a/tests/unit/fitting/minimizers/test_minimizer_base.py b/tests/unit_tests/fitting/minimizers/test_minimizer_base.py similarity index 78% rename from tests/unit/fitting/minimizers/test_minimizer_base.py rename to tests/unit_tests/fitting/minimizers/test_minimizer_base.py index 86ec4292..e4fcb005 100644 --- a/tests/unit/fitting/minimizers/test_minimizer_base.py +++ b/tests/unit_tests/fitting/minimizers/test_minimizer_base.py @@ -1,31 +1,30 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +import pytest + +from unittest.mock import MagicMock 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() @@ -35,8 +34,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): @@ -47,51 +46,35 @@ 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): @@ -116,9 +99,16 @@ 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 @@ -127,7 +117,11 @@ 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 @@ -165,16 +159,12 @@ 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 @@ -187,7 +177,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 @@ -213,3 +203,4 @@ 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/fitting/minimizers/test_minimizer_bumps.py b/tests/unit_tests/fitting/minimizers/test_minimizer_bumps.py similarity index 77% rename from tests/unit/fitting/minimizers/test_minimizer_bumps.py rename to tests/unit_tests/fitting/minimizers/test_minimizer_bumps.py index ba86b4d0..703b0617 100644 --- a/tests/unit/fitting/minimizers/test_minimizer_bumps.py +++ b/tests/unit_tests/fitting/minimizers/test_minimizer_bumps.py @@ -1,23 +1,21 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +import pytest 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 @@ -29,8 +27,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: @@ -44,13 +42,10 @@ 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() @@ -59,9 +54,7 @@ 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) @@ -77,9 +70,8 @@ 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 @@ -93,22 +85,12 @@ 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 @@ -117,22 +99,20 @@ 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): @@ -145,7 +125,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() @@ -172,9 +152,7 @@ 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 @@ -192,29 +170,22 @@ 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/fitting/minimizers/test_minimizer_dfo.py b/tests/unit_tests/fitting/minimizers/test_minimizer_dfo.py similarity index 58% rename from tests/unit/fitting/minimizers/test_minimizer_dfo.py rename to tests/unit_tests/fitting/minimizers/test_minimizer_dfo.py index e1d5eeef..439afea0 100644 --- a/tests/unit/fitting/minimizers/test_minimizer_dfo.py +++ b/tests/unit_tests/fitting/minimizers/test_minimizer_dfo.py @@ -1,46 +1,44 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +import pytest 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 @@ -51,53 +49,55 @@ 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,92 +135,98 @@ 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): @@ -235,26 +241,28 @@ 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 @@ -268,40 +276,46 @@ 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 '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' + 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" 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/fitting/minimizers/test_minimizer_lmfit.py b/tests/unit_tests/fitting/minimizers/test_minimizer_lmfit.py similarity index 75% rename from tests/unit/fitting/minimizers/test_minimizer_lmfit.py rename to tests/unit_tests/fitting/minimizers/test_minimizer_lmfit.py index ac280873..1185082f 100644 --- a/tests/unit/fitting/minimizers/test_minimizer_lmfit.py +++ b/tests/unit_tests/fitting/minimizers/test_minimizer_lmfit.py @@ -1,25 +1,22 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +import pytest 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 import Parameter from easyscience.fitting.minimizers.minimizer_lmfit import LMFit +from easyscience import Parameter +from lmfit import Parameter as LMParameter 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 @@ -30,22 +27,11 @@ 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): @@ -55,9 +41,7 @@ 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 @@ -71,12 +55,10 @@ 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 @@ -85,9 +67,7 @@ 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 @@ -101,12 +81,10 @@ 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 @@ -114,7 +92,6 @@ 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() @@ -128,9 +105,7 @@ 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') @@ -147,9 +122,7 @@ 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: @@ -166,9 +139,7 @@ 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: @@ -180,24 +151,10 @@ 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 @@ -212,16 +169,14 @@ 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() @@ -231,10 +186,7 @@ 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 @@ -243,9 +195,7 @@ 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']) @@ -254,18 +204,13 @@ 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 @@ -279,15 +224,7 @@ 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 @@ -349,12 +286,10 @@ 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' @@ -363,22 +298,18 @@ 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/fitting/test_fitter.py b/tests/unit_tests/fitting/test_fitter.py similarity index 88% rename from tests/unit/fitting/test_fitter.py rename to tests/unit_tests/fitting/test_fitter.py index 73f5a12a..dede119c 100644 --- a/tests/unit/fitting/test_fitter.py +++ b/tests/unit_tests/fitting/test_fitter.py @@ -1,17 +1,13 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - from unittest.mock import MagicMock -import numpy as np import pytest - +import numpy as np import easyscience.fitting.fitter -from easyscience import AvailableMinimizers from easyscience import Fitter +from easyscience import AvailableMinimizers -class TestFitter: +class TestFitter(): @pytest.fixture def fitter(self, monkeypatch): monkeypatch.setattr(Fitter, '_update_minimizer', MagicMock()) @@ -24,7 +20,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) @@ -92,7 +88,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() @@ -131,32 +127,23 @@ 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 @@ -174,7 +161,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 @@ -193,9 +180,7 @@ 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() @@ -206,7 +191,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' @@ -215,8 +200,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]) @@ -225,11 +210,10 @@ 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_tests/global_object/__init__.py b/tests/unit_tests/global_object/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/global_object/test_entry_list_comprehensive.py b/tests/unit_tests/global_object/test_entry_list_comprehensive.py similarity index 88% rename from tests/unit/global_object/test_entry_list_comprehensive.py rename to tests/unit_tests/global_object/test_entry_list_comprehensive.py index 7a15ba2f..e8c038fe 100644 --- a/tests/unit/global_object/test_entry_list_comprehensive.py +++ b/tests/unit_tests/global_object/test_entry_list_comprehensive.py @@ -1,71 +1,72 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# 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 Parameter -from easyscience import global_object +import easyscience 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): @@ -15,7 +11,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 @@ -23,30 +19,24 @@ 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): @@ -60,7 +50,7 @@ def test_singleton_behavior(self): # When obj1 = GlobalObject() obj2 = GlobalObject() - + # Then assert obj1 is obj2 assert id(obj1) == id(obj2) @@ -71,24 +61,23 @@ 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 @@ -97,70 +86,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 @@ -169,9 +158,8 @@ 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/global_object/test_integration_comprehensive.py b/tests/unit_tests/global_object/test_integration_comprehensive.py similarity index 76% rename from tests/unit/global_object/test_integration_comprehensive.py rename to tests/unit_tests/global_object/test_integration_comprehensive.py index 61268954..1ea9f584 100644 --- a/tests/unit/global_object/test_integration_comprehensive.py +++ b/tests/unit_tests/global_object/test_integration_comprehensive.py @@ -1,21 +1,21 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - -import gc -from unittest.mock import patch +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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() + assert unique_name in global_obj.map.vertices() \ No newline at end of file diff --git a/tests/unit/global_object/test_map.py b/tests/unit_tests/global_object/test_map.py similarity index 84% rename from tests/unit/global_object/test_map.py rename to tests/unit_tests/global_object/test_map.py index c68aa96f..a2783e6e 100644 --- a/tests/unit/global_object/test_map.py +++ b/tests/unit_tests/global_object/test_map.py @@ -1,135 +1,133 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project = 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 @@ -577,20 +568,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 @@ -600,10 +591,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 @@ -611,14 +602,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') @@ -626,34 +617,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 @@ -662,10 +653,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 @@ -675,7 +666,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) @@ -683,20 +674,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 @@ -705,10 +696,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 @@ -717,18 +708,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.""" @@ -736,10 +727,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 @@ -749,9 +740,10 @@ 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/global_object/test_undo_redo.py b/tests/unit_tests/global_object/test_undo_redo.py similarity index 77% rename from tests/unit/global_object/test_undo_redo.py rename to tests/unit_tests/global_object/test_undo_redo.py index be39eac3..212681ac 100644 --- a/tests/unit/global_object/test_undo_redo.py +++ b/tests/unit_tests/global_object/test_undo_redo.py @@ -1,35 +1,36 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project np.ndarray: @@ -306,7 +304,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 @@ -315,17 +313,16 @@ 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'), @@ -350,41 +347,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/global_object/test_undo_redo_comprehensive.py b/tests/unit_tests/global_object/test_undo_redo_comprehensive.py similarity index 83% rename from tests/unit/global_object/test_undo_redo_comprehensive.py rename to tests/unit_tests/global_object/test_undo_redo_comprehensive.py index 05264c1b..024731a7 100644 --- a/tests/unit/global_object/test_undo_redo_comprehensive.py +++ b/tests/unit_tests/global_object/test_undo_redo_comprehensive.py @@ -1,150 +1,142 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - -from unittest.mock import MagicMock -from unittest.mock import patch +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# 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/io/test_serializer_base.py b/tests/unit_tests/io/test_serializer_base.py similarity index 73% rename from tests/unit/io/test_serializer_base.py rename to tests/unit_tests/io/test_serializer_base.py index c3c8dd21..728dd1b6 100644 --- a/tests/unit/io/test_serializer_base.py +++ b/tests/unit_tests/io/test_serializer_base.py @@ -1,67 +1,63 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2021-2025 Contributors to the EasyScience project 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""" @@ -93,138 +90,150 @@ 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 = { @@ -240,40 +249,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 @@ -285,42 +294,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 @@ -328,87 +337,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 @@ -417,22 +426,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 @@ -443,77 +452,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) @@ -524,29 +533,33 @@ 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) @@ -556,16 +569,15 @@ 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): @@ -573,60 +585,64 @@ 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) @@ -635,20 +651,25 @@ 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) @@ -658,10 +679,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 @@ -672,40 +693,39 @@ 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 @@ -713,4 +733,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 + assert result['array1'].dtype == np.int64 \ No newline at end of file diff --git a/tests/unit_tests/io/test_serializer_component.py b/tests/unit_tests/io/test_serializer_component.py new file mode 100644 index 00000000..80994b4d --- /dev/null +++ b/tests/unit_tests/io/test_serializer_component.py @@ -0,0 +1,97 @@ + +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/io/test_serializer_dict.py b/tests/unit_tests/io/test_serializer_dict.py similarity index 79% rename from tests/unit/io/test_serializer_dict.py rename to tests/unit_tests/io/test_serializer_dict.py index 1ddf21ef..7d75f02d 100644 --- a/tests/unit/io/test_serializer_dict.py +++ b/tests/unit_tests/io/test_serializer_dict.py @@ -1,19 +1,17 @@ -# 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: @@ -38,7 +36,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) @@ -61,13 +59,12 @@ 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) @@ -79,12 +76,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) @@ -96,26 +93,25 @@ 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) + assert isinstance(d["b"], dict) \ No newline at end of file diff --git a/tests/unit_tests/legacy/test_dict.py b/tests/unit_tests/legacy/test_dict.py new file mode 100644 index 00000000..70af9d78 --- /dev/null +++ b/tests/unit_tests/legacy/test_dict.py @@ -0,0 +1,156 @@ + +# 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 new file mode 100644 index 00000000..651bd950 --- /dev/null +++ b/tests/unit_tests/legacy/test_json.py @@ -0,0 +1,123 @@ + +# 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 new file mode 100644 index 00000000..7094de85 --- /dev/null +++ b/tests/unit_tests/legacy/test_xml.py @@ -0,0 +1,111 @@ + +# 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 new file mode 100644 index 00000000..bb769856 --- /dev/null +++ b/tests/unit_tests/models/__init__.py @@ -0,0 +1,4 @@ +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2025 Contributors to the EasyScience project + diff --git a/tests/unit/models/test_polynomial.py b/tests/unit_tests/models/test_polynomial.py similarity index 92% rename from tests/unit/models/test_polynomial.py rename to tests/unit_tests/models/test_polynomial.py index 5376d03e..2493cd11 100644 --- a/tests/unit/models/test_polynomial.py +++ b/tests/unit_tests/models/test_polynomial.py @@ -1,5 +1,7 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause +# SPDX-FileCopyrightText: 2025 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +# © 2025 Contributors to the EasyScience project + import numpy as np import pytest @@ -17,18 +19,18 @@ def clear(): poly_test_cases = ( - (1.0,), + (1.,), ( - 1.0, - 2.0, + 1., + 2., ), - (1.0, 2.0, 3.0), - (-1.0, -2.0, -3.0), + (1., 2., 3.), + (-1., -2., -3.), (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) @@ -124,7 +126,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'): @@ -186,7 +188,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_tests/variable/__init__.py b/tests/unit_tests/variable/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/variable/test_descriptor_any_type.py b/tests/unit_tests/variable/test_descriptor_any_type.py similarity index 56% rename from tests/unit/variable/test_descriptor_any_type.py rename to tests/unit_tests/variable/test_descriptor_any_type.py index 5dc28b58..70c4cc65 100644 --- a/tests/unit/variable/test_descriptor_any_type.py +++ b/tests/unit_tests/variable/test_descriptor_any_type.py @@ -1,48 +1,43 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - -import numpy as np import pytest +import numpy as np -from easyscience import global_object from easyscience.variable import DescriptorAnyType - +from easyscience import global_object 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 @@ -53,14 +48,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 @@ -80,4 +75,4 @@ def test_copy(self, descriptor: DescriptorAnyType): # Expect assert type(descriptor_copy) == DescriptorAnyType - assert descriptor_copy._value == descriptor._value + assert descriptor_copy._value == descriptor._value \ No newline at end of file diff --git a/tests/unit_tests/variable/test_descriptor_array.py b/tests/unit_tests/variable/test_descriptor_array.py new file mode 100644 index 00000000..695f5fe2 --- /dev/null +++ b/tests/unit_tests/variable/test_descriptor_array.py @@ -0,0 +1,1356 @@ +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 new file mode 100644 index 00000000..aeeb823e --- /dev/null +++ b/tests/unit_tests/variable/test_descriptor_base.py @@ -0,0 +1,166 @@ +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/tests/unit/variable/test_descriptor_bool.py b/tests/unit_tests/variable/test_descriptor_bool.py similarity index 69% rename from tests/unit/variable/test_descriptor_bool.py rename to tests/unit_tests/variable/test_descriptor_bool.py index 3c181f0e..4be20657 100644 --- a/tests/unit/variable/test_descriptor_bool.py +++ b/tests/unit_tests/variable/test_descriptor_bool.py @@ -1,25 +1,21 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - import pytest -from easyscience import global_object from easyscience.variable import DescriptorBool - +from easyscience import global_object 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() @@ -29,22 +25,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, ) @@ -59,7 +55,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): @@ -78,4 +74,4 @@ def test_copy(self, descriptor: DescriptorBool): # Expect assert type(descriptor_copy) == DescriptorBool - assert descriptor_copy._bool_value == descriptor._bool_value + assert descriptor_copy._bool_value == descriptor._bool_value \ No newline at end of file diff --git a/tests/unit/variable/test_descriptor_number.py b/tests/unit_tests/variable/test_descriptor_number.py similarity index 58% rename from tests/unit/variable/test_descriptor_number.py rename to tests/unit_tests/variable/test_descriptor_number.py index 6abd3029..5dc4e060 100644 --- a/tests/unit/variable/test_descriptor_number.py +++ b/tests/unit_tests/variable/test_descriptor_number.py @@ -1,25 +1,22 @@ -# 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 @@ -31,79 +28,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, ) @@ -113,33 +110,23 @@ 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') @@ -147,7 +134,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' @@ -164,7 +151,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 @@ -176,7 +163,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 @@ -185,6 +172,7 @@ 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 @@ -201,7 +189,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 @@ -212,14 +200,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() @@ -227,25 +215,10 @@ 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 @@ -256,12 +229,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 @@ -271,53 +244,27 @@ 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 @@ -332,8 +279,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 @@ -343,27 +290,16 @@ 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): @@ -371,25 +307,10 @@ 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 @@ -410,36 +331,19 @@ 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 @@ -458,40 +362,31 @@ 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 @@ -501,65 +396,53 @@ 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 @@ -568,12 +451,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) @@ -582,5 +465,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 + assert result.unit == "m" + assert result.variance == 0.1 \ No newline at end of file diff --git a/tests/unit/variable/test_descriptor_str.py b/tests/unit_tests/variable/test_descriptor_str.py similarity index 59% rename from tests/unit/variable/test_descriptor_str.py rename to tests/unit_tests/variable/test_descriptor_str.py index 46acc847..aa593ed9 100644 --- a/tests/unit/variable/test_descriptor_str.py +++ b/tests/unit_tests/variable/test_descriptor_str.py @@ -1,64 +1,60 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - import pytest -from easyscience import global_object from easyscience.variable import DescriptorStr - +from easyscience import global_object 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): @@ -77,4 +73,4 @@ def test_copy(self, descriptor: DescriptorStr): # Expect assert type(descriptor_copy) == DescriptorStr - assert descriptor_copy._string == descriptor._string + assert descriptor_copy._string == descriptor._string \ No newline at end of file diff --git a/tests/unit/variable/test_parameter.py b/tests/unit_tests/variable/test_parameter.py similarity index 64% rename from tests/unit/variable/test_parameter.py rename to tests/unit_tests/variable/test_parameter.py index 87c1ce4f..f2b756eb 100644 --- a/tests/unit/variable/test_parameter.py +++ b/tests/unit_tests/variable/test_parameter.py @@ -1,17 +1,14 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - -from unittest.mock import MagicMock - -import numpy as np import pytest +from unittest.mock import MagicMock import scipp as sc +import numpy as np + from scipp import UnitError -from easyscience import DescriptorNumber -from easyscience import ObjBase from easyscience import Parameter +from easyscience import DescriptorNumber from easyscience import global_object +from easyscience import ObjBase class TestParameter: @@ -19,15 +16,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, ) @@ -36,9 +33,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, @@ -61,20 +58,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 == [] @@ -86,15 +83,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, ) @@ -107,15 +104,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, ) @@ -123,18 +120,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 @@ -149,95 +146,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( @@ -245,34 +242,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 @@ -281,46 +278,48 @@ 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 @@ -328,23 +327,27 @@ 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 @@ -358,44 +361,48 @@ 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 = {} @@ -406,10 +413,13 @@ 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 @@ -420,7 +430,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"' @@ -431,28 +441,30 @@ 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( @@ -461,48 +473,50 @@ 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) @@ -510,13 +524,15 @@ 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 == [] @@ -527,9 +543,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 @@ -542,7 +558,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 @@ -554,19 +570,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 @@ -581,20 +597,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 == [] @@ -606,9 +622,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) @@ -620,13 +636,15 @@ 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 @@ -644,18 +662,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 @@ -673,7 +691,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, @@ -684,33 +702,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) @@ -734,39 +752,45 @@ 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 @@ -784,9 +808,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 @@ -808,9 +832,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 @@ -824,107 +848,113 @@ 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): @@ -937,16 +967,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): @@ -976,7 +1006,10 @@ 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 @@ -984,7 +1017,8 @@ def test_repr_fixed(self, parameter: Parameter): # Then Expect assert ( - repr(parameter) == "" + repr(parameter) + == "" ) def test_value_match_callback(self, parameter: Parameter): @@ -1015,14 +1049,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 @@ -1032,14 +1066,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 @@ -1049,9 +1083,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 @@ -1079,25 +1113,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, @@ -1128,11 +1162,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 @@ -1141,14 +1175,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 @@ -1156,7 +1190,9 @@ 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 @@ -1166,7 +1202,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 @@ -1174,25 +1210,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 @@ -1202,25 +1238,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, @@ -1251,12 +1287,14 @@ 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 @@ -1265,21 +1303,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 @@ -1288,14 +1326,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 @@ -1303,7 +1341,9 @@ 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 @@ -1313,7 +1353,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 @@ -1321,25 +1361,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 @@ -1349,25 +1389,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, @@ -1399,24 +1439,26 @@ 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 @@ -1438,20 +1480,20 @@ def test_multiplication_with_parameter_nan_cases(self, test, expected, expected_ 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 @@ -1483,20 +1525,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 @@ -1527,27 +1569,29 @@ 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() @@ -1573,28 +1617,28 @@ def test_division_with_parameter(self, parameter: Parameter, test, expected, exp 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): @@ -1610,20 +1654,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 @@ -1653,17 +1697,19 @@ 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() @@ -1678,43 +1724,45 @@ def test_zero_value_divided_by_parameter(self, parameter: Parameter, test, expec 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 @@ -1727,9 +1775,9 @@ def test_division_with_descriptor_number_missing_cases(self, first, second, expe 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 @@ -1741,38 +1789,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 @@ -1788,59 +1836,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): @@ -1856,26 +1904,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): @@ -1885,7 +1933,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 @@ -1893,24 +1941,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/variable/test_parameter_dependency_serialization.py b/tests/unit_tests/variable/test_parameter_dependency_serialization.py similarity index 61% rename from tests/unit/variable/test_parameter_dependency_serialization.py rename to tests/unit_tests/variable/test_parameter_dependency_serialization.py index 62feb5f3..574e2497 100644 --- a/tests/unit/variable/test_parameter_dependency_serialization.py +++ b/tests/unit_tests/variable/test_parameter_dependency_serialization.py @@ -1,20 +1,22 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause - -import json - import pytest +import json +from copy import deepcopy +from unittest.mock import Mock -from easyscience import Parameter -from easyscience import global_object -from easyscience.variable.parameter_dependency_resolver import deserialize_and_resolve_parameters +from easyscience import Parameter, global_object +from easyscience.variable.parameter_dependency_resolver import ( + resolve_all_parameter_dependencies, +) from easyscience.variable.parameter_dependency_resolver import ( get_parameters_with_pending_dependencies, ) -from easyscience.variable.parameter_dependency_resolver import resolve_all_parameter_dependencies +from easyscience.variable.parameter_dependency_resolver import ( + deserialize_and_resolve_parameters, +) class TestParameterDependencySerialization: + @pytest.fixture def clear_global_map(self): """This fixture pattern: @@ -37,15 +39,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() @@ -60,53 +62,55 @@ 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() @@ -115,8 +119,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) @@ -126,32 +130,34 @@ 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() @@ -160,8 +166,8 @@ def test_dependency_resolution_after_deserialization_desired_unit(self, clear_gl 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) @@ -171,24 +177,24 @@ def test_dependency_resolution_after_deserialization_desired_unit(self, clear_gl # 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 @@ -196,26 +202,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 @@ -225,21 +231,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) @@ -254,26 +260,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 @@ -281,7 +287,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() @@ -292,13 +298,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.""" @@ -306,12 +312,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 @@ -319,12 +325,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) @@ -333,24 +339,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(): @@ -360,8 +366,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) @@ -370,9 +376,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 @@ -383,7 +389,9 @@ 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): @@ -391,9 +399,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) @@ -405,31 +413,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 @@ -440,13 +448,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() @@ -458,41 +466,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() @@ -502,27 +510,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/tools/add_spdx.py b/tools/add_spdx.py deleted file mode 100644 index 295a7e0d..00000000 --- a/tools/add_spdx.py +++ /dev/null @@ -1,149 +0,0 @@ -"""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 deleted file mode 100644 index 80555ab1..00000000 --- a/tools/check_spdx.py +++ /dev/null @@ -1,43 +0,0 @@ -"""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 deleted file mode 100644 index 50e547a7..00000000 --- a/tools/remove_spdx.py +++ /dev/null @@ -1,39 +0,0 @@ -"""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 deleted file mode 100644 index 2d347579..00000000 --- a/tools/test_scripts.py +++ /dev/null @@ -1,55 +0,0 @@ -"""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 deleted file mode 100644 index 26c7c41b..00000000 --- a/tools/update_docs_assets.py +++ /dev/null @@ -1,91 +0,0 @@ -""" -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 deleted file mode 100644 index 8ec8c2d7..00000000 --- a/tools/update_github_labels.py +++ /dev/null @@ -1,339 +0,0 @@ -"""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())