Skip to content

Commit

Permalink
Backport PR jupyterlite#169: Adopt ruff, black, fix various issues
Browse files Browse the repository at this point in the history
  • Loading branch information
jtpio authored and meeseeksmachine committed Dec 5, 2023
1 parent a8d0939 commit 7c7d4b1
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Expand Up @@ -29,7 +29,7 @@ jobs:
set -eux
jlpm
jlpm run build
jlpm run eslint:check
jlpm run lint:check
python -m pip install -v .
jupyter labextension list 2>&1 | grep -ie "@jupyterlite/xeus-python-kernel.*OK"
Expand Down
2 changes: 0 additions & 2 deletions docs/conf.py
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-

extensions = [
"jupyterlite_sphinx",
"myst_parser",
Expand Down
2 changes: 2 additions & 0 deletions environment.yml
Expand Up @@ -14,3 +14,5 @@ dependencies:
- empack >=3,<4
- nodejs=20
- mamba
- black
- ruff
10 changes: 5 additions & 5 deletions jupyterlite_xeus_python/__init__.py
Expand Up @@ -5,12 +5,12 @@
# in editable mode with pip. It is highly recommended to install
# the package from a stable release or in editable mode: https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs
import warnings
warnings.warn("Importing 'jupyterlite-xeus-python' outside a proper installation.")

warnings.warn(
"Importing 'jupyterlite-xeus-python' outside a proper installation.", stacklevel=2
)
__version__ = "dev"


def _jupyter_labextension_paths():
return [{
"src": "labextension",
"dest": "@jupyterlite/xeus-python-kernel"
}]
return [{"src": "labextension", "dest": "@jupyterlite/xeus-python-kernel"}]
60 changes: 33 additions & 27 deletions jupyterlite_xeus_python/build.py
@@ -1,21 +1,18 @@
import csv
import os
from copy import copy
from pathlib import Path
import requests
import shutil
from subprocess import check_call, run, DEVNULL
import sys
from pathlib import Path
from subprocess import run
from tempfile import TemporaryDirectory
from typing import List
from typing import List, Optional
from urllib.parse import urlparse
import sys

import requests
import typer
import yaml

from empack.pack import pack_env, DEFAULT_CONFIG_PATH
from empack.file_patterns import PkgFileFilter, pkg_file_filter_from_yaml

import typer
from empack.pack import DEFAULT_CONFIG_PATH, pack_env

try:
from mamba.api import create as mamba_create
Expand All @@ -40,6 +37,7 @@
]

PLATFORM = "emscripten-32"
DEFAULT_REQUEST_TIMEOUT = 1 # in minutes


def create_env(
Expand Down Expand Up @@ -131,10 +129,12 @@ def _install_pip_dependencies(prefix_path, dependencies, log=None):
if log is not None:
log.warning(
"""
Installing pip dependencies. This is very much experimental so use this feature at your own risks.
Installing pip dependencies. This is very much experimental so use
this feature at your own risks.
Note that you can only install pure-python packages.
pip is being run with the --no-deps option to not pull undesired system-specific dependencies, so please
install your package dependencies from emscripten-forge or conda-forge.
pip is being run with the --no-deps option to not pull undesired
system-specific dependencies, so please install your package dependencies
from emscripten-forge or conda-forge.
"""
)

Expand All @@ -144,6 +144,8 @@ def _install_pip_dependencies(prefix_path, dependencies, log=None):

run(
[
sys.executable,
"-m",
"pip",
"install",
*dependencies,
Expand All @@ -166,7 +168,7 @@ def _install_pip_dependencies(prefix_path, dependencies, log=None):
packages_dist_info = Path(pkg_dir.name).glob("*.dist-info")

for package_dist_info in packages_dist_info:
with open(package_dist_info / "RECORD", "r") as record:
with open(package_dist_info / "RECORD") as record:
record_content = record.read()
record_csv = csv.reader(record_content.splitlines())
all_files = [_file[0] for _file in record_csv]
Expand All @@ -181,7 +183,7 @@ def _install_pip_dependencies(prefix_path, dependencies, log=None):
with open(package_dist_info / "RECORD", "w") as record:
record.write(fixed_record_data)

non_supported_files = [".so", ".a", ".dylib", ".lib", ".exe" ".dll"]
non_supported_files = [".so", ".a", ".dylib", ".lib", ".exe.dll"]

# COPY files under `prefix_path`
for _file, inside_site_packages in files:
Expand All @@ -208,10 +210,10 @@ def _install_pip_dependencies(prefix_path, dependencies, log=None):
shutil.copy(src_path, dest_path)


def build_and_pack_emscripten_env(
def build_and_pack_emscripten_env( # noqa: C901, PLR0912, PLR0915
python_version: str = PYTHON_VERSION,
xeus_python_version: str = XEUS_PYTHON_VERSION,
packages: List[str] = [],
packages: Optional[List[str]] = None,
environment_file: str = "",
root_prefix: str = "/tmp/xeus-python-kernel",
env_name: str = "xeus-python-kernel",
Expand All @@ -222,13 +224,13 @@ def build_and_pack_emscripten_env(
log=None,
):
"""Build a conda environment for the emscripten platform and pack it with empack."""
if packages is None:
packages = []
channels = CHANNELS
specs = [
f"python={python_version}",
"xeus-lite",
"xeus-python"
if not xeus_python_version
else f"xeus-python={xeus_python_version}",
"xeus-python" if not xeus_python_version else f"xeus-python={xeus_python_version}",
*packages,
]
bail_early = True
Expand Down Expand Up @@ -261,13 +263,17 @@ def build_and_pack_emscripten_env(
elif isinstance(dependency, dict) and dependency.get("pip") is not None:
# If it's a local Python package, make its path relative to the environment file
pip_dependencies = [
((env_file.parent / pip_dep).resolve() if os.path.isdir(env_file.parent / pip_dep) else pip_dep)
(
(env_file.parent / pip_dep).resolve()
if os.path.isdir(env_file.parent / pip_dep)
else pip_dep
)
for pip_dep in dependency["pip"]
]

# Bail early if there is nothing to do
if bail_early and not force:
return []
return ""

orig_config = os.environ.get("CONDARC")

Expand All @@ -294,7 +300,9 @@ def build_and_pack_emscripten_env(
if empack_config:
empack_config_is_url = urlparse(empack_config).scheme in ("http", "https")
if empack_config_is_url:
empack_config_content = requests.get(empack_config).content
empack_config_content = requests.get(
empack_config, timeout=DEFAULT_REQUEST_TIMEOUT
).content
pack_kwargs["file_filters"] = PkgFileFilter.parse_obj(
yaml.safe_load(empack_config_content)
)
Expand Down Expand Up @@ -324,7 +332,7 @@ def build_and_pack_emscripten_env(
dirs_exist_ok=True,
)

with open(Path(output_path) / "worker.ts", "r") as fobj:
with open(Path(output_path) / "worker.ts") as fobj:
worker = fobj.read()

worker = worker.replace("XEUS_KERNEL_FILE", "'xpython_wasm.js'")
Expand Down Expand Up @@ -356,9 +364,7 @@ def build_and_pack_emscripten_env(
def main(
python_version: str = PYTHON_VERSION,
xeus_python_version: str = XEUS_PYTHON_VERSION,
packages: List[str] = typer.Option(
[], help="The list of packages you want to install"
),
packages: List[str] = typer.Option([], help="The list of packages you want to install"),
environment_file: str = typer.Option(
"", help="The path to the environment.yml file you want to use"
),
Expand Down
29 changes: 8 additions & 21 deletions jupyterlite_xeus_python/env_build_addon.py
Expand Up @@ -2,27 +2,17 @@
import json
import os
from pathlib import Path
import requests
import shutil
from subprocess import check_call, run, DEVNULL
from tempfile import TemporaryDirectory
from urllib.parse import urlparse

import yaml

from traitlets import List, Unicode

from empack.pack import pack_env, DEFAULT_CONFIG_PATH
from empack.file_patterns import PkgFileFilter, pkg_file_filter_from_yaml

from jupyterlite_core.addons.federated_extensions import FederatedExtensionAddon
from jupyterlite_core.constants import (
SHARE_LABEXTENSIONS,
LAB_EXTENSIONS,
FEDERATED_EXTENSIONS,
JUPYTERLITE_JSON,
LAB_EXTENSIONS,
SHARE_LABEXTENSIONS,
UTF8,
FEDERATED_EXTENSIONS,
)
from jupyterlite_core.addons.federated_extensions import FederatedExtensionAddon
from traitlets import List, Unicode

from .build import XEUS_PYTHON_VERSION, build_and_pack_emscripten_env

Expand All @@ -42,9 +32,8 @@ class XeusPythonEnv(FederatedExtensionAddon):
)

empack_config = Unicode(
None,
"",
config=True,
allow_none=True,
description="The path or URL to the empack config file",
)

Expand All @@ -64,7 +53,7 @@ class XeusPythonEnv(FederatedExtensionAddon):
)

def __init__(self, *args, **kwargs):
super(XeusPythonEnv, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

self.cwd = TemporaryDirectory()

Expand Down Expand Up @@ -140,9 +129,7 @@ def safe_copy_extension(self, pkg_json):
stem = json.loads(pkg_json.read_text(**UTF8))["name"]
dest = self.output_extensions / stem
file_dep = [
p
for p in pkg_path.rglob("*")
if not (p.is_dir() or self.is_ignored_sourcemap(p.name))
p for p in pkg_path.rglob("*") if not (p.is_dir() or self.is_ignored_sourcemap(p.name))
]

yield dict(
Expand Down
10 changes: 8 additions & 2 deletions package.json
Expand Up @@ -44,8 +44,14 @@
"eslint": "jlpm eslint:check --fix",
"eslint:check": "eslint . --cache --ext .ts,.tsx",
"install:extension": "jlpm build",
"lint": "jlpm stylelint && jlpm prettier && jlpm eslint",
"lint:check": "jlpm stylelint:check && jlpm prettier:check && jlpm eslint:check",
"lint": "jlpm stylelint && jlpm prettier && jlpm eslint && jlpm lint:py",
"lint:check": "jlpm stylelint:check && jlpm prettier:check && jlpm eslint:check && jlpm lint:py:check",
"lint:py": "jlpm lint:py:black && jlpm lint:py:ruff --fix-only",
"lint:py:check": "jlpm lint:py:black:check && jlpm lint:py:ruff:check",
"lint:py:black": "black .",
"lint:py:black:check": "black . --check",
"lint:py:ruff": "ruff .",
"lint:py:ruff:check": "ruff check .",
"prettier": "jlpm prettier:base --write --list-different",
"prettier:base": "prettier \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md}\"",
"prettier:check": "jlpm prettier:base --check",
Expand Down
54 changes: 54 additions & 0 deletions pyproject.toml
Expand Up @@ -30,6 +30,12 @@ dependencies = [
]
dynamic = ["version", "description", "authors", "urls", "keywords"]

[project.optional-dependencies]
dev = [
"black",
"ruff==0.0.292",
]

[project.scripts]
jupyterlite-xeus-python-build = "jupyterlite_xeus_python.build:start"

Expand Down Expand Up @@ -85,3 +91,51 @@ before-build-python = ["jlpm clean:all"]

[tool.check-wheel-contents]
ignore = ["W002"]

[tool.black]
line-length = 100
target-version = ["py38"]

[tool.ruff]
target-version = "py38"
exclude = [
"*/tests/*",
"docs",
]
line-length = 100
select = [
"A", "B", "C", "DTZ", "E", "EM", "F", "FBT", "I", "ICN", "ISC", "N",
"PLC", "PLE", "PLR", "PLW", "Q", "RUF", "S", "SIM", "T", "TID", "UP",
"W", "YTT",
]
ignore = [
"D100",
"D104",
# Q000 Single quotes found but double quotes preferred
"Q000",
# FBT001 Boolean positional arg in function definition
"FBT001", "FBT002", "FBT003",
# C408 Unnecessary `dict` call (rewrite as a literal)
"C408", "C416",
# allow for using print()
"T201",
# PLR0913 Too many arguments to function call
"PLR0913",
# extended flake8 ignore
"D104", "D100", "EM101",
# Probable insecure usage of temporary file or directory
"S108",
# RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
"RUF012",
]

[tool.ruff.per-file-ignores]
# S101 Use of `assert` detected
# F841 Local variable `foo` is assigned to but never used
# PLR2004 Magic value used in comparison
"tests/*" = ["S101", "F841", "PLR2004"]

# B008 Do not perform function call `typer.Option` in argument defaults
# E501 `subprocess` call: check for execution of untrusted input
# S603 `subprocess` call: check for execution of untrusted input
"jupyterlite_xeus_python/build.py" = ["B008", "E501", "S603"]
4 changes: 2 additions & 2 deletions style/base.css
@@ -1,5 +1,5 @@
/*-----------------------------------------------------------------------------
/* -----------------------------------------------------------------------------
| Copyright (c) Thorsten Beier
| Copyright (c) Jupyter Development Team.
| Distributed under the terms of the Modified BSD License.
|----------------------------------------------------------------------------*/
|---------------------------------------------------------------------------- */
4 changes: 2 additions & 2 deletions style/index.css
@@ -1,7 +1,7 @@
/*-----------------------------------------------------------------------------
/* -----------------------------------------------------------------------------
| Copyright (c) Thorsten Beier
| Copyright (c) Jupyter Development Team.
| Distributed under the terms of the Modified BSD License.
|----------------------------------------------------------------------------*/
|---------------------------------------------------------------------------- */

@import url('base.css');
2 changes: 1 addition & 1 deletion tests/test_package/test_package/hey.py
@@ -1 +1 @@
print('Hey')
print("Hey")

0 comments on commit 7c7d4b1

Please sign in to comment.