Preflight 1.3.0 (#114)

pull/116/head
Nicholas Bollweg 2023-04-10 09:09:29 -05:00 zatwierdzone przez GitHub
rodzic 3765c72391
commit f5f6c639aa
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
16 zmienionych plików z 149 dodań i 128 usunięć

Wyświetl plik

@ -102,6 +102,7 @@ dependencies:
- ssort - ssort
# unit testing # unit testing
- pytest - pytest
- pytest-cov
- pytest-console-scripts - pytest-console-scripts
- pytest-html - pytest-html
- pytest-jupyter-server - pytest-jupyter-server

Wyświetl plik

@ -50,6 +50,7 @@ dependencies:
- ssort - ssort
# unit testing # unit testing
- pytest - pytest
- pytest-cov
- pytest-console-scripts - pytest-console-scripts
- pytest-html - pytest-html
- pytest-jupyter-server - pytest-jupyter-server

Wyświetl plik

@ -0,0 +1,49 @@
<!--
Thanks for contributing to ipydrawio!
Please fill out the following items to submit a pull request.
See the contributing guidelines for more information:
https://github.com/deathbeds/ipydrawio/blob/master/CONTRIBUTING.md
-->
## References
<!-- Note issue numbers this pull request addresses (should be at least one, see contributing guidelines above). -->
<!-- Note any other pull requests that address this issue and how this pull request is different. -->
## Code changes
<!-- Describe the code changes and how they address the issue. -->
## User-facing changes
<!-- Describe any visual or user interaction changes and how they address the issue. -->
<!-- For visual changes, include before and after screenshots here. -->
## Backwards-incompatible changes
<!-- Describe any backwards-incompatible changes to IPyDrawio public APIs. -->
## Chores
- [ ] ran `doit lint`
- [ ] updated `CHANGELOG.md`
- [ ] validated on binder
- [ ] validated on ReadTheDocs
<!--
# Copyright 2023 ipydrawio contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-->

Wyświetl plik

@ -45,5 +45,5 @@ jobs:
issue_number: context.issue.number, issue_number: context.issue.number,
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
body: `Try this PR on [![](${LITE})](${RTD}) :arrow_left: ReadTheDocs or Binder :arrow_right: [![](${BND})](${BH})`, body: `Try this PR on [![RTD](${LITE})](${RTD}) :arrow_left: ReadTheDocs or Binder :arrow_right: [![Binder](${BND})](${BH})`,
}); });

Wyświetl plik

@ -91,7 +91,7 @@ jobs:
if: steps.cache-node-modules.outputs.cache-hit != 'true' if: steps.cache-node-modules.outputs.cache-hit != 'true'
id: cache-yarn-packages id: cache-yarn-packages
with: with:
path: .yarn-packages path: ./build/.cache/.yarn-packages
key: | key: |
${{ env.CACHE_EPOCH }}-yarn-${{ runner.os }}-${{ hashFiles('yarn.lock') }} ${{ env.CACHE_EPOCH }}-yarn-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
restore-keys: | restore-keys: |
@ -296,21 +296,13 @@ jobs:
cd ../ipydrawio-mathjax cd ../ipydrawio-mathjax
codecov --root ../.. codecov --root ../..
- name: upload (utest) - name: upload (reports)
if: always() if: always()
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: |- name: |-
ipydrawio-${{ github.run_number }}-utest-${{ matrix.os }}-${{ matrix.python-version }} ipydrawio-${{ github.run_number }}-reports-${{ matrix.os }}-${{matrix.python-version }}
path: ./build/pytest path: ./build/reports
- name: upload (atest)
if: always()
uses: actions/upload-artifact@v3
with:
name: |-
ipydrawio-${{ github.run_number }}-atest-${{ matrix.os }}-${{matrix.python-version }}
path: ./build/atest
- name: Rename uncached conda packages - name: Rename uncached conda packages
shell: bash shell: bash
@ -343,7 +335,7 @@ jobs:
if: steps.cache-node-modules.outputs.cache-hit != 'true' if: steps.cache-node-modules.outputs.cache-hit != 'true'
id: cache-yarn-packages id: cache-yarn-packages
with: with:
path: .yarn-packages path: ./build/.cache/.yarn-packages
key: | key: |
${{ env.CACHE_EPOCH }}-yarn-${{ runner.os }}-${{ hashFiles('yarn.lock') }} ${{ env.CACHE_EPOCH }}-yarn-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
restore-keys: | restore-keys: |
@ -399,7 +391,7 @@ jobs:
if: steps.cache-node-modules.outputs.cache-hit != 'true' if: steps.cache-node-modules.outputs.cache-hit != 'true'
id: cache-yarn-packages id: cache-yarn-packages
with: with:
path: .yarn-packages path: ./build/.cache/.yarn-packages
key: | key: |
${{ env.CACHE_EPOCH }}-yarn-${{ runner.os }}-${{ hashFiles('yarn.lock') }} ${{ env.CACHE_EPOCH }}-yarn-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
restore-keys: | restore-keys: |
@ -430,12 +422,12 @@ jobs:
shell: bash -l {0} shell: bash -l {0}
run: doit test:robot run: doit test:robot
- name: upload (atest) - name: upload (reports)
if: always() if: always()
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: |- name: |-
ipydrawio-${{ github.run_number }}-atest-${{ matrix.os }}${{ matrix.python-version }} ipydrawio-${{ github.run_number }}-reports-${{ matrix.os }}${{ matrix.python-version }}
path: ./build/atest path: ./build/atest
- name: upload (docs) - name: upload (docs)

Wyświetl plik

@ -3,5 +3,5 @@ ignore-scripts true
network-timeout "300000" network-timeout "300000"
prefer-offline true prefer-offline true
registry "https://registry.npmjs.org/" registry "https://registry.npmjs.org/"
yarn-offline-mirror "./.yarn-packages" yarn-offline-mirror "./build/.cache/.yarn-packages"
yarn-offline-mirror-pruning true yarn-offline-mirror-pruning true

Wyświetl plik

@ -14,11 +14,12 @@
## Prerequisites ## Prerequisites
- `jupyterlab >=3,<4`
- `nodejs >=12`
- `doit >=0.32` - `doit >=0.32`
- `jupyterlab >=3,<4`
- `nodejs >=18,<19`
- `python >=3.8`
### Recommended: conda ### Recommended: `mamba`
- Get [Miniforge/Mambaforge](https://github.com/conda-forge/miniforge/releases) - Get [Miniforge/Mambaforge](https://github.com/conda-forge/miniforge/releases)
@ -76,38 +77,12 @@ doit dist
## Releasing ## Releasing
- [ ] start a release issue with a checklist (maybe like this one) - Start a [release] issue on GitHub
- [ ] merge all outstanding PRs - Follow the checklist
- [ ] ensure the versions have been bumped (check with `doit test:integrity`)
- [ ] ensure the CHANGELOG is up-to-date
- [ ] move the new release to the top of the stack
- [ ] validate on binder
- [ ] validate on ReadTheDocs
- [ ] wait for a successful build of `master`
- [ ] download the `dist` archive and unpack somewhere (maybe a fresh `dist`)
- [ ] create a new release through the GitHub UI
- [ ] paste in the relevant CHANGELOG entries
- [ ] upload the artifacts
- [ ] actually upload to npm.com, pypi.org
```bash
cd dist
twine upload ipydrawio*
npm login
npm publish deathbeds-ipydrawio-$VERSION.tgz
npm publish deathbeds-ipydrawio-jupyter-templates-$VERSION.tgz
npm publish deathbeds-ipydrawio-notebook-$VERSION.tgz
npm publish deathbeds-ipydrawio-pdf-$VERSION.tgz
npm publish deathbeds-ipydrawio-webpack-$OTHER_VERSION.tgz
npm logout
```
- [ ] postmortem
- [ ] handle `conda-forge` feedstock tasks
- [ ] validate on binder via simplest-possible gists
- [ ] activate the version on ReadTheDocs
- [ ] bump to next development version
- [ ] update release procedures
``` [release]: https://github.com/deathbeds/ipydrawio/issues/new?template=release.md
<!--
Copyright 2023 ipydrawio contributors Copyright 2023 ipydrawio contributors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -121,4 +96,4 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
``` -->

Wyświetl plik

@ -12,7 +12,8 @@
"ignore_sys_prefix": true, "ignore_sys_prefix": true,
"lite_dir": ".", "lite_dir": ".",
"output_archive": "../build/demo/ipydrawio-lite-1.3.0.tgz", "output_archive": "../build/demo/ipydrawio-lite-1.3.0.tgz",
"output_dir": "../build/demo" "output_dir": "../build/demo",
"cache_dir": "../build/.cache/.lite"
}, },
"PipliteAddon": { "PipliteAddon": {
"piplite_urls": [ "piplite_urls": [

Wyświetl plik

@ -73,6 +73,7 @@ dependencies:
- ssort - ssort
# unit testing # unit testing
- pytest - pytest
- pytest-cov
- pytest-console-scripts - pytest-console-scripts
- pytest-html - pytest-html
- pytest-jupyter-server - pytest-jupyter-server

64
dodo.py
Wyświetl plik

@ -942,14 +942,10 @@ def task_provision():
) )
def _pytest(setup_py, pycov_args, pytest_args): def _pytest(setup_py, pytest_args):
return CmdAction( return CmdAction(
[ [
*P.PYM, *P.PYM,
"coverage",
"run",
*pycov_args,
"-m",
"pytest", "pytest",
*P.PYTEST_ARGS, *P.PYTEST_ARGS,
*pytest_args, *pytest_args,
@ -963,30 +959,6 @@ def _pytest(setup_py, pycov_args, pytest_args):
) )
def _pycov_combine(setup_py):
return CmdAction(
[*P.PYM, "coverage", "combine"],
shell=False,
cwd=str(setup_py.parent),
)
def _pycov_report(setup_py):
return CmdAction(
[*P.PYM, "coverage", "report", "--skip-covered", "--show-missing"],
shell=False,
cwd=str(setup_py.parent),
)
def _pycov_html(setup_py, *pycov_html_args):
return CmdAction(
[*P.PYM, "coverage", "html", *pycov_html_args],
shell=False,
cwd=str(setup_py.parent),
)
def task_test(): def task_test():
"""Run tests.""" """Run tests."""
if not P.TESTING_IN_CI: if not P.TESTING_IN_CI:
@ -1006,24 +978,39 @@ def task_test():
P.SCRIPTS / "integrity.py", P.SCRIPTS / "integrity.py",
], ],
"actions": [ "actions": [
["python", "-m", "pytest", "--pyargs", "scripts.integrity", "-vv"], [
*P.PYM,
"pytest",
"--pyargs",
"scripts.integrity",
"-vv",
*("-o", f"""cache_dir={P.CACHE / ".pytest.integrity"}"""),
],
], ],
}, },
P.OK_INTEGRITY, P.OK_INTEGRITY,
) )
for pkg, setup in P.PY_SETUP.items(): for pkg, setup in P.PY_SETUP.items():
html = P.BUILD / f"pytest/{pkg}/test.html" report_dir = P.REPORTS / "pytest" / pkg
htmlcov = P.BUILD / f"pytest/{pkg}/htmlcov" html = report_dir / "pytest.html"
cov_index = report_dir / "htmlcov" / "index.html"
cache_dir = P.CACHE / f".pytest.{pkg}"
pytest_args = [ pytest_args = [
"-vv", "-vv",
"--tb=long", "--tb=long",
*("-o", f"cache_dir={cache_dir}"),
# subs
"--script-launch-mode=subprocess",
# report
f"--html={html}", f"--html={html}",
"--self-contained-html", "--self-contained-html",
"--script-launch-mode=subprocess", # cov
"--cov-context=test",
f"""--cov={pkg.replace("-", "_")}""",
f"--cov-report=html:{cov_index.parent}",
"--cov-branch",
] ]
pycov_args = []
pycov_html_args = [f"--directory={htmlcov.parent}"]
if pkg == P.IPD.name: if pkg == P.IPD.name:
pytest_args += ["-n", "auto"] pytest_args += ["-n", "auto"]
@ -1041,12 +1028,9 @@ def task_test():
], ],
"actions": [ "actions": [
(P.delete_some, [html]), (P.delete_some, [html]),
_pytest(setup, pycov_args, pytest_args), _pytest(setup, pytest_args),
_pycov_combine(setup),
_pycov_html(setup, *pycov_html_args),
_pycov_report(setup),
], ],
"targets": [html], "targets": [html, cov_index],
}, },
P.OK_PYTEST[pkg], P.OK_PYTEST[pkg],
) )

Wyświetl plik

@ -39,7 +39,6 @@ classifiers =
License :: OSI Approved :: Apache Software License License :: OSI Approved :: Apache Software License
Programming Language :: Python Programming Language :: Python
Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.10
@ -85,3 +84,6 @@ source_pkgs =
ipydrawio_export ipydrawio_export
concurrency = multiprocessing concurrency = multiprocessing
parallel = True parallel = True
[coverage:html]
show_contexts = True

Wyświetl plik

@ -39,7 +39,6 @@ classifiers =
License :: OSI Approved :: Apache Software License License :: OSI Approved :: Apache Software License
Programming Language :: Python Programming Language :: Python
Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.10
@ -73,3 +72,6 @@ source_pkgs =
ipydrawio_mathjax ipydrawio_mathjax
concurrency = multiprocessing concurrency = multiprocessing
parallel = True parallel = True
[coverage:html]
show_contexts = True

Wyświetl plik

@ -37,7 +37,6 @@ classifiers =
License :: OSI Approved :: Apache Software License License :: OSI Approved :: Apache Software License
Programming Language :: Python Programming Language :: Python
Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.10
@ -72,3 +71,6 @@ source_pkgs =
ipydrawio_widgets ipydrawio_widgets
concurrency = multiprocessing concurrency = multiprocessing
parallel = True parallel = True
[coverage:html]
show_contexts = True

Wyświetl plik

@ -40,7 +40,6 @@ classifiers =
License :: OSI Approved :: Apache Software License License :: OSI Approved :: Apache Software License
Programming Language :: Python Programming Language :: Python
Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.10
@ -91,3 +90,6 @@ source_pkgs =
ipydrawio ipydrawio
concurrency = multiprocessing concurrency = multiprocessing
parallel = True parallel = True
[coverage:html]
show_contexts = True

Wyświetl plik

@ -1,6 +1,6 @@
[tool.ruff] [tool.ruff]
fix = true fix = true
cache-dir = "build/.cache/ruff" cache-dir = "build/.cache/.ruff"
ignore = [ ignore = [
"BLE001", "BLE001",
"E501", "E501",

Wyświetl plik

@ -136,15 +136,19 @@ YARN_INTEGRITY = NODE_MODULES / ".yarn-integrity"
YARN_LOCK = ROOT / "yarn.lock" YARN_LOCK = ROOT / "yarn.lock"
DODO = ROOT / "dodo.py" DODO = ROOT / "dodo.py"
BUILD = ROOT / "build" BUILD = ROOT / "build"
REPORTS = BUILD / "reports"
OK = BUILD / "ok"
DIST = ROOT / "dist" DIST = ROOT / "dist"
DOCS = ROOT / "docs" DOCS = ROOT / "docs"
README = ROOT / "README.md" README = ROOT / "README.md"
CHANGELOG = ROOT / "CHANGELOG.md" CHANGELOG = ROOT / "CHANGELOG.md"
CACHE = BUILD / ".cache"
# external URLs # external URLs
# archive.org template # archive.org template
CACHE_EPOCH = 0 CACHE_EPOCH = 0
HTTP_CACHE = BUILD / ".requests-cache" HTTP_CACHE = CACHE / ".requests-cache"
BLACK_CACHE_DIR = CACHE / ".black"
def A_O(archive_id, url, cache_bust=CACHE_EPOCH): def A_O(archive_id, url, cache_bust=CACHE_EPOCH):
@ -200,7 +204,7 @@ EXAMPLE_IPYNB = _clean(EXAMPLES.rglob("*.ipynb"))
DIST_NBHTML = DIST / "nbsmoke" DIST_NBHTML = DIST / "nbsmoke"
ATEST = ROOT / "atest" ATEST = ROOT / "atest"
ATEST_DIO = _clean(ATEST.rglob("*.dio"), ATEST.rglob("*.dio.svg")) ATEST_DIO = _clean(ATEST.rglob("*.dio"), ATEST.rglob("*.dio.svg"))
ATEST_OUT = BUILD / "atest" ATEST_OUT = REPORTS / "atest"
ATEST_OUT_XML = "output.xml" ATEST_OUT_XML = "output.xml"
ATEST_TEMPLATES = [*ATEST.rglob("*.robot.j2")] ATEST_TEMPLATES = [*ATEST.rglob("*.robot.j2")]
@ -365,7 +369,7 @@ JS_PKG_PACK = {
for k, v in JS_TSBUILDINFO.items() for k, v in JS_TSBUILDINFO.items()
if not k.startswith("_") if not k.startswith("_")
] ]
OK_PYSETUP = {k: BUILD / f"pysetup.{k}.ok" for k, v in PY_SETUP.items()} OK_PYSETUP = {k: OK / f"pysetup.{k}.ok" for k, v in PY_SETUP.items()}
PY_SETUP_DEPS = { PY_SETUP_DEPS = {
IPD: lambda: [OK_PYSETUP["ipydrawio-widgets"]], IPD: lambda: [OK_PYSETUP["ipydrawio-widgets"]],
@ -557,32 +561,32 @@ JS_PKG_PACK[IPDM.name][0] += [IPDWP_IGNORE, IPDWP_APP, *ALL_IPDM_JS, IPDM_STARTU
IPYDRAWIO_DATA_DIR = Path(sys.prefix) / "share/jupyter/ipydrawio_export" IPYDRAWIO_DATA_DIR = Path(sys.prefix) / "share/jupyter/ipydrawio_export"
# built files # built files
OK_PIP_CHECK = BUILD / "pip.check.ok" OK_PIP_CHECK = OK / "pip.check.ok"
OK_INTEGRITY = BUILD / "integrity.ok" OK_INTEGRITY = OK / "integrity.ok"
OK_SUBMODULES = BUILD / "submodules.ok" OK_SUBMODULES = OK / "submodules.ok"
OK_BLACK = BUILD / "black.ok" OK_BLACK = OK / "black.ok"
OK_BLACK_JUPYTER = BUILD / "black.jupyter.ok" OK_BLACK_JUPYTER = OK / "black.jupyter.ok"
OK_NBQA_RUFF = BUILD / "nbqa.ruff.ok" OK_NBQA_RUFF = OK / "nbqa.ruff.ok"
OK_RUFF = BUILD / "ruff.ok" OK_RUFF = OK / "ruff.ok"
OK_FLAKE8 = BUILD / "flake8.ok" OK_FLAKE8 = OK / "flake8.ok"
OK_SSORT = BUILD / "ssort.ok" OK_SSORT = OK / "ssort.ok"
OK_LINT = BUILD / "lint.ok" OK_LINT = OK / "lint.ok"
OK_ROBOTIDY = BUILD / "robot.tidy.ok" OK_ROBOTIDY = OK / "robot.tidy.ok"
OK_PRETTIER = BUILD / "prettier.ok" OK_PRETTIER = OK / "prettier.ok"
OK_ESLINT = BUILD / "eslint.ok" OK_ESLINT = OK / "eslint.ok"
OK_JS_BUILD_PRE = BUILD / "js.build.pre.ok" OK_JS_BUILD_PRE = OK / "js.build.pre.ok"
OK_JS_BUILD = BUILD / "js.build.ok" OK_JS_BUILD = OK / "js.build.ok"
OK_PYTEST = {k: BUILD / f"pytest.{k}.ok" for k, v in PY_SETUP.items()} OK_PYTEST = {k: OK / f"pytest.{k}.ok" for k, v in PY_SETUP.items()}
OK_SERVEREXT = {k: BUILD / f"serverext.{k}.ok" for k, v in SERVER_EXT.items()} OK_SERVEREXT = {k: OK / f"serverext.{k}.ok" for k, v in SERVER_EXT.items()}
OK_PROVISION = BUILD / "provision.ok" OK_PROVISION = OK / "provision.ok"
OK_ROBOT_DRYRUN = BUILD / "robot.dryrun.ok" OK_ROBOT_DRYRUN = OK / "robot.dryrun.ok"
OK_ROBOCOP = BUILD / "robot.robocop.ok" OK_ROBOCOP = OK / "robot.robocop.ok"
OK_DIOLINT = BUILD / "dio.lint.ok" OK_DIOLINT = OK / "dio.lint.ok"
OK_ATEST = BUILD / "atest.ok" OK_ATEST = OK / "atest.ok"
OK_CONDA_TEST = BUILD / "conda-build.test.ok" OK_CONDA_TEST = OK / "conda-build.test.ok"
OK_LINK_CHECK = BUILD / "pytest-check-links.ok" OK_LINK_CHECK = OK / "pytest-check-links.ok"
OK_EXT_BUILD = {k: BUILD / f"ext.build.{k}.ok" for k in JS_LABEXT_PY_HOST} OK_EXT_BUILD = {k: OK / f"ext.build.{k}.ok" for k in JS_LABEXT_PY_HOST}
PY_TEST_DEP.setdefault("ipydrawio-export", []).append(OK_PROVISION) PY_TEST_DEP.setdefault("ipydrawio-export", []).append(OK_PROVISION)
@ -829,7 +833,11 @@ def _ok(task, ok):
task["actions"] = [ task["actions"] = [
lambda: [ok.exists() and ok.unlink(), True][-1], lambda: [ok.exists() and ok.unlink(), True][-1],
*task["actions"], *task["actions"],
lambda: [ok.parent.mkdir(exist_ok=True), ok.write_text("ok", **ENC), True][-1], lambda: [
ok.parent.mkdir(exist_ok=True, parents=True),
ok.write_text("ok", **ENC),
True,
][-1],
] ]
return task return task
@ -1068,4 +1076,5 @@ os.environ.update(
JUPYTER_PLATFORM_DIRS="1", JUPYTER_PLATFORM_DIRS="1",
PYDEVD_DISABLE_FILE_VALIDATION="1", PYDEVD_DISABLE_FILE_VALIDATION="1",
IPYDRAWIO_DATA_DIR=str(IPYDRAWIO_DATA_DIR), IPYDRAWIO_DATA_DIR=str(IPYDRAWIO_DATA_DIR),
BLACK_CACHE_DIR=str(BLACK_CACHE_DIR),
) )