Skip to content

Commit

Permalink
[Import-linter] Find more import errors in import linter pipeline. (m…
Browse files Browse the repository at this point in the history
…icrosoft#2933)

# Description

Import linter cannot find items other than static imports.
We can add some more import statement in poetry and find circular import
dynamically.

Automatic imports:
Since we have different processes, just dynamic import the module in
different process is OK.


![image](https://github.com/microsoft/promptflow/assets/2208599/c76eed17-e2ab-4d45-b449-dfc99c1f408a)


# All Promptflow Contribution checklist:
- [ ] **The pull request does not introduce [breaking changes].**
- [ ] **CHANGELOG is updated for new features, bug fixes or other
significant changes.**
- [ ] **I have read the [contribution guidelines](../CONTRIBUTING.md).**
- [ ] **Create an issue and link to the pull request to get dedicated
review from promptflow team. Learn more: [suggested
workflow](../CONTRIBUTING.md#suggested-workflow).**

## General Guidelines and Best Practices
- [ ] Title of the pull request is clear and informative.
- [ ] There are a small number of commits, each of which have an
informative message. This means that previously merged commits do not
appear in the history of the PR. For more information on cleaning up the
commits in your PR, [see this
page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md).

### Testing Guidelines
- [ ] Pull request includes test coverage for the included changes.
  • Loading branch information
crazygao authored Apr 29, 2024
1 parent ea1c37b commit ab29afd
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 15 deletions.
1 change: 1 addition & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@
"autogen",
"spawnve",
"addrs",
"pycache",
"pywin",
"STARTF",
"mltable",
Expand Down
39 changes: 24 additions & 15 deletions .github/workflows/promptflow-import-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,16 @@ jobs:
- uses: snok/install-poetry@v1
- name: Install all packages
run: |
cd ${{ env.WORKING_DIRECTORY }}/src/promptflow-tracing
touch promptflow/__init__.py
poetry install --with dev
cd ${{ env.WORKING_DIRECTORY }}/src/promptflow-core
touch promptflow/__init__.py
poetry install --with dev
cd ${{ env.WORKING_DIRECTORY }}/src/promptflow-devkit
touch promptflow/__init__.py
poetry install --with dev
cd ${{ env.WORKING_DIRECTORY }}/src/promptflow-azure
touch promptflow/__init__.py
poetry install --with dev
cd ${{ env.WORKING_DIRECTORY }}/src/promptflow-evals
touch promptflow/__init__.py
poetry install --with dev
touch src/promptflow-tracing/promptflow/__init__.py
poetry install --with dev -C ${{ env.WORKING_DIRECTORY }}/src/promptflow-tracing
touch src/promptflow-core/promptflow/__init__.py
poetry install --with dev -C ${{ env.WORKING_DIRECTORY }}/src/promptflow-core
touch src/promptflow-devkit/promptflow/__init__.py
poetry install --with dev -C ${{ env.WORKING_DIRECTORY }}/src/promptflow-devkit
touch src/promptflow-azure/promptflow/__init__.py
poetry install --with dev -C ${{ env.WORKING_DIRECTORY }}/src/promptflow-azure
touch src/promptflow-evals/promptflow/__init__.py
poetry install --with dev -C ${{ env.WORKING_DIRECTORY }}/src/promptflow-evals
working-directory: ${{ env.WORKING_DIRECTORY }}
- name: import lint
run: |
Expand All @@ -59,4 +54,18 @@ jobs:
cd ${{ env.WORKING_DIRECTORY }}/src/promptflow-evals
poetry run lint-imports
working-directory: ${{ env.WORKING_DIRECTORY }}
- name: import lint testing private imports from global
working-directory: ${{ env.WORKING_DIRECTORY }}/src/promptflow-azure
run: |
set -xe
rm ${{ env.WORKING_DIRECTORY }}/src/promptflow-tracing/promptflow/__init__.py
rm ${{ env.WORKING_DIRECTORY }}/src/promptflow-core/promptflow/__init__.py
rm ${{ env.WORKING_DIRECTORY }}/src/promptflow-devkit/promptflow/__init__.py
rm ${{ env.WORKING_DIRECTORY }}/src/promptflow-azure/promptflow/__init__.py
rm ${{ env.WORKING_DIRECTORY }}/src/promptflow-evals/promptflow/__init__.py
echo "=== Add more import linter when facing more import errors ==="
echo "=== promptflow-azure full lints ==="
poetry run pip install langchain
poetry run python ${{ github.workspace }}/scripts/import_linter/import_linter.py
56 changes: 56 additions & 0 deletions scripts/import_linter/import_linter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import os
import subprocess
import multiprocessing
import importlib

git_base = subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).decode().strip()


def walk_and_ignore_pycache(directory):
list = []
for root, dirnames, files in os.walk(directory, topdown=True):
# This line removes any __pycache__ directories from the list
dirnames[:] = [d for d in dirnames if d != '__pycache__' and d != 'tests' and d != 'data']
filenames = [f for f in files if f.endswith('.py') and not f.startswith('__init__')]
for filename in filenames:
# Process files as you would like
list.append(os.path.join(root, filename))
return list


def file_to_import(file):
push_file = []
head_tail = os.path.split(file)
while head_tail[1] != "promptflow" and head_tail[0] != "":
if head_tail[1].endswith(".py"):
push_file.insert(0, head_tail[1][:-3])
else:
push_file.insert(0, head_tail[1])
file = head_tail[0]
head_tail = os.path.split(file)
push_file.insert(0, "promptflow")
return ".".join(push_file)


# If there is an import error, the process will exit with a non-zero exit code
# Find this importlib.import_module as the keyword to search for the error
# The error below this is the import error / circular import error.
def subprocess_check_python_import(file):
print(f'Checking import of {file} on process ID: {os.getpid()}')
importlib.import_module(file)


def process_file(file):
import_name = file_to_import(file)
subprocess_check_python_import(import_name)


if __name__ == '__main__':
pool = multiprocessing.Pool()
list = walk_and_ignore_pycache(git_base + "/src/promptflow-tracing/")
list.extend(walk_and_ignore_pycache(git_base + "/src/promptflow-core/"))
list.extend(walk_and_ignore_pycache(git_base + "/src/promptflow-devkit/"))
list.extend(walk_and_ignore_pycache(git_base + "/src/promptflow-azure/"))
pool.map(process_file, list)
pool.close()
pool.join()

0 comments on commit ab29afd

Please sign in to comment.