upgrade-python-3

Upgrade your Python codebase from version 3.x -> 3.11

Example

constants:
  context_depth: 3

  #placeholder
  ignore_file_paths:
    - 'gulpfile.js'
    - 'LICENSE'
    - '**/test/**'
    - 'test/**'
    - 'package.json'
    - '.gitignore'
    - 'tsconfig.json'
    - 'README.md'
    - '**/{{ react_directory }}'
    - '**/{{ react_directory }}/**'
    - '**/Scripts/**'
    - '**/Content/**'
    - '**/Config/**'
    - '*.cs'
    - '*.xml'
    - '*.csproj'
    - '*.asax'
    - '*.config'

steps:
  # Build context graph
  - name: Indexing The Codebase
    tools:
      - name: find_files_by_name_with_regex
        arguments:
          find_file_name_pattern: '^(?!.*(__init__)).*\.py$'
        returns: files

      - name: build_dependency_graph_with_ai
        arguments:
          files_to_index: '{{ files }}'
          exclude_path_patterns: '{{ ignore_file_paths }}'

  # Update each requirements file
  - name: Upgrade to Python 3.11
    tools:
      - name: find_files_by_name_with_regex
        arguments:
          find_file_name_pattern: 'requirements*.txt|(^|/)(Pipfile)$|(^|/)(setup.py)$'
        returns: requirements_files

      - name: async_each
        items: '{{ requirements_files }}'
        each_item:
          item_name: requirements_file
          tools:
            - name: edit_file
              arguments:
                path_to_file: '{{ requirements_file }}'
                edit_prompt: |
                  Upgrade all libraries and dependencies for Python 3.11 compatibility.

                  # Instructions:
                  - **Python Version:** Ensure `python_version` is set to `=3.11` in Pipfile and setup.py. For requirements.txt, omit versioning.
                  - Ensure valid TOML formatting for Pipfile.
                  - Loosen pinned versions (`==`) to `>=` where newer versions are compatible with Python 3.11.
                  - If possible, try to keep versions as low as possible to ensure compatibility with the starting python version.
                  - Ensure the final file is free of hidden control/escape characters to ensure cross-platform usability (especially macOS).

            - name: get_file_context
              arguments:
                path_to_file: '{{ requirements_file }}'
                depth: '{{ context_depth }}'
                graph_type: 'embedding'
              returns: upgrade_file_context

            - name: ask
              arguments:
                question_prompt: |
                  We are performing an upgrade from python 3.x to python 3.11. We need to make sure third party library usages are still compatible

                  Given this context on the upgrade we are doing and new requirements,
                  ```
                  {{ upgrade_file_context }}
                  ```

                  ANSWER IN ONE OF TWO WAYS.

                  OPTION 1: Say "False" or "No". This is usually the case.
                  OPTION 2: Provide a list of ONLY the usage changes needed for the given libraries.

                  Be precise, concise, and only respond based on the given options. Be conservative, usually OPTION 1 is correct, 
                  only use OPTION 2 if you are VERY sure what needs to change for the given third party library. 

                  Please do not hallucinate, this is important.

              returns: required_refactors

            - name: ask_question
              arguments:
                question_prompt: |
                  Do we need to do refactors based on this? Say true or false, be conservative towards false. Be precise.
                  ```
                  {{ required_refactors }}
                  ```

                  This is important. Do not hallucinate please.
              returns: need_to_refactor

            - name: if_else
              condition: '{{ need_to_refactor }}'
              if:
                tools:
                  # Update files in order
                  - name: find_files_by_name_with_regex
                    arguments:
                      find_file_name_pattern: '^(?!.*(__init__)).*\.py$'
                    returns: files

                  - name: async_each
                    items: '{{ files }}'
                    each_item:
                      item_name: file
                      tools:
                        - name: make_variable
                          arguments:
                            value: |
                              Given these required refactors 
                              {{ required_refactors }}  

                              ONLY IF NECESSARY, ensure this file is compatible with the specified dependencies.
                              Otherwise do nothing.

                              Be conservative, usually not much needs to change.

                              We are only after third party library usage changes. If the library is unfamiliar, DO NOTHING.

                              If DOING NOTHING, do NOT respond with backticks "```" in any capacity. 

                              Do not hallucinate, this is important.
                          returns: refactor_prompt

                        - name: get_file_context
                          arguments:
                            path_to_file: '{{ file }}'
                            depth: '{{ context_depth }}'
                            graph_type: 'embedding'
                          returns: file_context

                        - name: edit_file
                          arguments:
                            path_to_file: '{{ file }}'
                            edit_prompt: |
                              '{{ file_context }}'
                              '{{ refactor_prompt }}'

                        - name: mark_files_converted_in_context
                          arguments:
                            old_file_path: '{{ file }}'
                            new_file_paths:
                              - '{{ file }}'

  - name: Create or Update .tool-versions file
    tools:
      - name: find_files_by_name_with_regex
        arguments:
          find_file_name_pattern: '\.tool-versions$'
        returns: tools_version_files
      - name: if_else
        condition: '{{ tools_version_files }}'
        if:
          tools:
            - name: edit_file
              arguments:
                path_to_file: '.tool-versions'
                edit_prompt: |
                  Update Python version to 3.11. If needed, use patch version 3.11.8.
        else:
          tools:
            - name: create_file
              arguments:
                path_to_file: '.tool-versions'
                file_contents: 'python 3.11.8'

Last updated