зеркало из https://github.com/microsoft/LightGBM.git
[ci] enable ruff-format on some files, add pre-commit config (#6308)
This commit is contained in:
Родитель
cc733f8595
Коммит
6330d6269c
|
@ -32,25 +32,26 @@ def get_runs(trigger_phrase):
|
|||
"""
|
||||
pr_runs = []
|
||||
if environ.get("GITHUB_EVENT_NAME", "") == "pull_request":
|
||||
pr_number = int(environ.get("GITHUB_REF").split('/')[-2])
|
||||
pr_number = int(environ.get("GITHUB_REF").split("/")[-2])
|
||||
page = 1
|
||||
while True:
|
||||
req = request.Request(
|
||||
url="{}/repos/microsoft/LightGBM/issues/{}/comments?page={}&per_page=100".format(
|
||||
environ.get("GITHUB_API_URL"),
|
||||
pr_number,
|
||||
page
|
||||
environ.get("GITHUB_API_URL"), pr_number, page
|
||||
),
|
||||
headers={"Accept": "application/vnd.github.v3+json"}
|
||||
headers={"Accept": "application/vnd.github.v3+json"},
|
||||
)
|
||||
url = request.urlopen(req)
|
||||
data = json.loads(url.read().decode('utf-8'))
|
||||
data = json.loads(url.read().decode("utf-8"))
|
||||
url.close()
|
||||
if not data:
|
||||
break
|
||||
runs_on_page = [i for i in data
|
||||
if i['author_association'].lower() in {'owner', 'member', 'collaborator'}
|
||||
and i['body'].startswith('/gha run {}'.format(trigger_phrase))]
|
||||
runs_on_page = [
|
||||
i
|
||||
for i in data
|
||||
if i["author_association"].lower() in {"owner", "member", "collaborator"}
|
||||
and i["body"].startswith("/gha run {}".format(trigger_phrase))
|
||||
]
|
||||
pr_runs.extend(runs_on_page)
|
||||
page += 1
|
||||
return pr_runs[::-1]
|
||||
|
@ -70,20 +71,20 @@ def get_status(runs):
|
|||
The most recent status of workflow.
|
||||
Can be 'success', 'failure' or 'in-progress'.
|
||||
"""
|
||||
status = 'success'
|
||||
status = "success"
|
||||
for run in runs:
|
||||
body = run['body']
|
||||
body = run["body"]
|
||||
if "Status: " in body:
|
||||
if "Status: skipped" in body:
|
||||
continue
|
||||
if "Status: failure" in body:
|
||||
status = 'failure'
|
||||
status = "failure"
|
||||
break
|
||||
if "Status: success" in body:
|
||||
status = 'success'
|
||||
status = "success"
|
||||
break
|
||||
else:
|
||||
status = 'in-progress'
|
||||
status = "in-progress"
|
||||
break
|
||||
return status
|
||||
|
||||
|
@ -92,8 +93,8 @@ if __name__ == "__main__":
|
|||
trigger_phrase = argv[1]
|
||||
while True:
|
||||
status = get_status(get_runs(trigger_phrase))
|
||||
if status != 'in-progress':
|
||||
if status != "in-progress":
|
||||
break
|
||||
sleep(60)
|
||||
if status == 'failure':
|
||||
if status == "failure":
|
||||
exit(1)
|
||||
|
|
|
@ -1,19 +1,8 @@
|
|||
#!/bin/sh
|
||||
|
||||
echo "running ruff"
|
||||
ruff check \
|
||||
--config=./python-package/pyproject.toml \
|
||||
. \
|
||||
|| exit 1
|
||||
echo "done running ruff"
|
||||
|
||||
echo "running isort"
|
||||
isort \
|
||||
--check-only \
|
||||
--settings-path=./python-package/pyproject.toml \
|
||||
. \
|
||||
|| exit 1
|
||||
echo "done running isort"
|
||||
echo "running pre-commit checks"
|
||||
pre-commit run --all-files || exit 1
|
||||
echo "done running pre-commit checks"
|
||||
|
||||
echo "running mypy"
|
||||
mypy \
|
||||
|
|
|
@ -74,10 +74,9 @@ if [[ $TASK == "lint" ]]; then
|
|||
${CONDA_PYTHON_REQUIREMENT} \
|
||||
cmakelint \
|
||||
cpplint \
|
||||
isort \
|
||||
mypy \
|
||||
'r-lintr>=3.1' \
|
||||
ruff
|
||||
'pre-commit>=3.6.0' \
|
||||
'r-lintr>=3.1'
|
||||
source activate $CONDA_ENV
|
||||
echo "Linting Python code"
|
||||
sh ${BUILD_DIRECTORY}/.ci/lint-python.sh || exit 1
|
||||
|
|
|
@ -20,7 +20,7 @@ if __name__ == "__main__":
|
|||
copyfile(source / "lib_lightgbm.dylib", osx_folder_path / "lib_lightgbm.dylib")
|
||||
copyfile(source / "lib_lightgbm.dll", windows_folder_path / "lib_lightgbm.dll")
|
||||
copyfile(source / "lightgbm.exe", windows_folder_path / "lightgbm.exe")
|
||||
version = (current_dir.parent / 'VERSION.txt').read_text(encoding='utf-8').strip().replace('rc', '-rc')
|
||||
version = (current_dir.parent / "VERSION.txt").read_text(encoding="utf-8").strip().replace("rc", "-rc")
|
||||
nuget_str = rf"""<?xml version="1.0"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||
<metadata>
|
||||
|
@ -75,6 +75,6 @@ if __name__ == "__main__":
|
|||
</Target>
|
||||
</Project>
|
||||
"""
|
||||
(current_dir / "LightGBM.nuspec").write_text(nuget_str, encoding='utf-8')
|
||||
(current_dir / "build" / "LightGBM.props").write_text(prop_str, encoding='utf-8')
|
||||
(current_dir / "build" / "LightGBM.targets").write_text(target_str, encoding='utf-8')
|
||||
(current_dir / "LightGBM.nuspec").write_text(nuget_str, encoding="utf-8")
|
||||
(current_dir / "build" / "LightGBM.props").write_text(prop_str, encoding="utf-8")
|
||||
(current_dir / "build" / "LightGBM.targets").write_text(target_str, encoding="utf-8")
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
exclude: |
|
||||
(?x)^(
|
||||
build|
|
||||
external_libs|
|
||||
lightgbm-python|
|
||||
lightgbm_r|
|
||||
)$
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.2.1
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff
|
||||
args: ["--config", "python-package/pyproject.toml"]
|
||||
# Run the formatter.
|
||||
- id: ruff-format
|
||||
args: ["--config", "python-package/pyproject.toml"]
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.13.2
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort (python)
|
||||
args: ["--settings-path", "python-package/pyproject.toml"]
|
|
@ -1,4 +1,10 @@
|
|||
LightGBM has been developed and used by many active community members. Your help is very valuable to make it better for everyone.
|
||||
# contributing
|
||||
|
||||
LightGBM has been developed and used by many active community members.
|
||||
|
||||
Your help is very valuable to make it better for everyone.
|
||||
|
||||
## How to Contribute
|
||||
|
||||
- Check for the [Roadmap](https://github.com/microsoft/LightGBM/projects/1) and the [Feature Requests Hub](https://github.com/microsoft/LightGBM/issues/2302), and submit pull requests to address chosen issue. If you need development guideline, you can check the [Development Guide](https://github.com/microsoft/LightGBM/blob/master/docs/Development-Guide.rst) or directly ask us in Issues/Pull Requests.
|
||||
- Contribute to the [tests](https://github.com/microsoft/LightGBM/tree/master/tests) to make it more reliable.
|
||||
|
@ -6,3 +12,17 @@ LightGBM has been developed and used by many active community members. Your help
|
|||
- Contribute to the [examples](https://github.com/microsoft/LightGBM/tree/master/examples) to share your experience with other users.
|
||||
- Add your stories and experience to [Awesome LightGBM](https://github.com/microsoft/LightGBM/blob/master/examples/README.md). If LightGBM helped you in a machine learning competition or some research application, we want to hear about it!
|
||||
- [Open an issue](https://github.com/microsoft/LightGBM/issues) to report problems or recommend new features.
|
||||
|
||||
## Development Guide
|
||||
|
||||
### Linting
|
||||
|
||||
Every commit in the repository is tested with multiple static analyzers.
|
||||
|
||||
When developing locally, run some of them using `pre-commit` ([pre-commit docs](https://pre-commit.com/)).
|
||||
|
||||
```shell
|
||||
pre-commit run --all-files
|
||||
```
|
||||
|
||||
That command will check for some issues and automatically reformat the code.
|
||||
|
|
124
docs/conf.py
124
docs/conf.py
|
@ -34,7 +34,7 @@ from sphinx.application import Sphinx
|
|||
from sphinx.errors import VersionRequirementError
|
||||
|
||||
CURR_PATH = Path(__file__).absolute().parent
|
||||
LIB_PATH = CURR_PATH.parent / 'python-package'
|
||||
LIB_PATH = CURR_PATH.parent / "python-package"
|
||||
sys.path.insert(0, str(LIB_PATH))
|
||||
|
||||
INTERNAL_REF_REGEX = compile(r"(?P<url>\.\/.+)(?P<extension>\.rst)(?P<anchor>$|#)")
|
||||
|
@ -65,29 +65,29 @@ class IgnoredDirective(Directive):
|
|||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
os.environ['LIGHTGBM_BUILD_DOC'] = '1'
|
||||
C_API = os.environ.get('C_API', '').lower().strip() != 'no'
|
||||
RTD = bool(os.environ.get('READTHEDOCS', ''))
|
||||
os.environ["LIGHTGBM_BUILD_DOC"] = "1"
|
||||
C_API = os.environ.get("C_API", "").lower().strip() != "no"
|
||||
RTD = bool(os.environ.get("READTHEDOCS", ""))
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
needs_sphinx = '2.1.0' # Due to sphinx.ext.napoleon, autodoc_typehints
|
||||
needs_sphinx = "2.1.0" # Due to sphinx.ext.napoleon, autodoc_typehints
|
||||
if needs_sphinx > sphinx.__version__:
|
||||
message = f'This project needs at least Sphinx v{needs_sphinx}'
|
||||
message = f"This project needs at least Sphinx v{needs_sphinx}"
|
||||
raise VersionRequirementError(message)
|
||||
|
||||
# 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.autodoc',
|
||||
'sphinx.ext.autosummary',
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.viewcode',
|
||||
'sphinx.ext.napoleon',
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.autosummary",
|
||||
"sphinx.ext.todo",
|
||||
"sphinx.ext.viewcode",
|
||||
"sphinx.ext.napoleon",
|
||||
"sphinx.ext.intersphinx",
|
||||
]
|
||||
|
||||
autodoc_default_flags = ['members', 'inherited-members', 'show-inheritance']
|
||||
autodoc_default_flags = ["members", "inherited-members", "show-inheritance"]
|
||||
autodoc_default_options = {
|
||||
"members": True,
|
||||
"inherited-members": True,
|
||||
|
@ -95,54 +95,54 @@ autodoc_default_options = {
|
|||
}
|
||||
# mock out modules
|
||||
autodoc_mock_imports = [
|
||||
'dask',
|
||||
'dask.distributed',
|
||||
'datatable',
|
||||
'graphviz',
|
||||
'matplotlib',
|
||||
'numpy',
|
||||
'pandas',
|
||||
'scipy',
|
||||
'scipy.sparse',
|
||||
"dask",
|
||||
"dask.distributed",
|
||||
"datatable",
|
||||
"graphviz",
|
||||
"matplotlib",
|
||||
"numpy",
|
||||
"pandas",
|
||||
"scipy",
|
||||
"scipy.sparse",
|
||||
]
|
||||
try:
|
||||
import sklearn # noqa: F401
|
||||
except ImportError:
|
||||
autodoc_mock_imports.append('sklearn')
|
||||
autodoc_mock_imports.append("sklearn")
|
||||
# hide type hints in API docs
|
||||
autodoc_typehints = "none"
|
||||
|
||||
# Generate autosummary pages. Output should be set with: `:toctree: pythonapi/`
|
||||
autosummary_generate = ['Python-API.rst']
|
||||
autosummary_generate = ["Python-API.rst"]
|
||||
|
||||
# Only the class' docstring is inserted.
|
||||
autoclass_content = 'class'
|
||||
autoclass_content = "class"
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
master_doc = "index"
|
||||
|
||||
# General information about the project.
|
||||
project = 'LightGBM'
|
||||
copyright = f'{datetime.datetime.now().year}, Microsoft Corporation'
|
||||
author = 'Microsoft Corporation'
|
||||
project = "LightGBM"
|
||||
copyright = f"{datetime.datetime.now().year}, Microsoft Corporation"
|
||||
author = "Microsoft Corporation"
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
html_logo = str(CURR_PATH / 'logo' / 'LightGBM_logo_grey_text.svg')
|
||||
html_logo = str(CURR_PATH / "logo" / "LightGBM_logo_grey_text.svg")
|
||||
|
||||
# The name of an image file (relative to this directory) to use as a favicon of
|
||||
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
html_favicon = str(CURR_PATH / '_static' / 'images' / 'favicon.ico')
|
||||
html_favicon = str(CURR_PATH / "_static" / "images" / "favicon.ico")
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
# The short X.Y version.
|
||||
version = (CURR_PATH.parent / 'VERSION.txt').read_text(encoding='utf-8').strip().replace('rc', '-rc')
|
||||
version = (CURR_PATH.parent / "VERSION.txt").read_text(encoding="utf-8").strip().replace("rc", "-rc")
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = version
|
||||
|
||||
|
@ -151,67 +151,68 @@ release = version
|
|||
#
|
||||
# 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'
|
||||
language = "en"
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This patterns also effect to html_static_path and html_extra_path
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'default'
|
||||
pygments_style = "default"
|
||||
|
||||
# -- Configuration for C API docs generation ------------------------------
|
||||
|
||||
if C_API:
|
||||
extensions.extend([
|
||||
'breathe',
|
||||
])
|
||||
breathe_projects = {
|
||||
"LightGBM": str(CURR_PATH / 'doxyoutput' / 'xml')
|
||||
}
|
||||
extensions.extend(
|
||||
[
|
||||
"breathe",
|
||||
]
|
||||
)
|
||||
breathe_projects = {"LightGBM": str(CURR_PATH / "doxyoutput" / "xml")}
|
||||
breathe_default_project = "LightGBM"
|
||||
breathe_domain_by_extension = {
|
||||
"h": "c",
|
||||
}
|
||||
breathe_show_define_initializer = True
|
||||
c_id_attributes = ['LIGHTGBM_C_EXPORT']
|
||||
c_id_attributes = ["LIGHTGBM_C_EXPORT"]
|
||||
|
||||
# -- 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_rtd_theme'
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
|
||||
# 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 = {
|
||||
'includehidden': False,
|
||||
'logo_only': True,
|
||||
"includehidden": False,
|
||||
"logo_only": True,
|
||||
}
|
||||
|
||||
# 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']
|
||||
html_static_path = ["_static"]
|
||||
|
||||
# -- Options for HTMLHelp output ------------------------------------------
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'LightGBMdoc'
|
||||
htmlhelp_basename = "LightGBMdoc"
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
latex_logo = str(CURR_PATH / 'logo' / 'LightGBM_logo_black_text_small.png')
|
||||
latex_logo = str(CURR_PATH / "logo" / "LightGBM_logo_black_text_small.png")
|
||||
|
||||
# intersphinx configuration
|
||||
intersphinx_mapping = {
|
||||
"sklearn": ("https://scikit-learn.org/stable/", None),
|
||||
}
|
||||
|
||||
|
||||
def generate_doxygen_xml(app: Sphinx) -> None:
|
||||
"""Generate XML documentation for C API by Doxygen.
|
||||
|
||||
|
@ -238,18 +239,17 @@ def generate_doxygen_xml(app: Sphinx) -> None:
|
|||
"SORT_BRIEF_DOCS=YES",
|
||||
"WARN_AS_ERROR=YES",
|
||||
]
|
||||
doxygen_input = '\n'.join(doxygen_args)
|
||||
doxygen_input = "\n".join(doxygen_args)
|
||||
doxygen_input = bytes(doxygen_input, "utf-8")
|
||||
(CURR_PATH / 'doxyoutput').mkdir(parents=True, exist_ok=True)
|
||||
(CURR_PATH / "doxyoutput").mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
# Warning! The following code can cause buffer overflows on RTD.
|
||||
# Consider suppressing output completely if RTD project silently fails.
|
||||
# Refer to https://github.com/svenevs/exhale
|
||||
# /blob/fe7644829057af622e467bb529db6c03a830da99/exhale/deploy.py#L99-L111
|
||||
process = Popen(["doxygen", "-"],
|
||||
stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||
process = Popen(["doxygen", "-"], stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||
stdout, stderr = process.communicate(doxygen_input)
|
||||
output = '\n'.join([i.decode('utf-8') for i in (stdout, stderr) if i is not None])
|
||||
output = "\n".join([i.decode("utf-8") for i in (stdout, stderr) if i is not None])
|
||||
if process.returncode != 0:
|
||||
raise RuntimeError(output)
|
||||
else:
|
||||
|
@ -296,11 +296,9 @@ def generate_r_docs(app: Sphinx) -> None:
|
|||
# Consider suppressing output completely if RTD project silently fails.
|
||||
# Refer to https://github.com/svenevs/exhale
|
||||
# /blob/fe7644829057af622e467bb529db6c03a830da99/exhale/deploy.py#L99-L111
|
||||
process = Popen(['/bin/bash'],
|
||||
stdin=PIPE, stdout=PIPE, stderr=PIPE,
|
||||
universal_newlines=True)
|
||||
process = Popen(["/bin/bash"], stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True)
|
||||
stdout, stderr = process.communicate(commands)
|
||||
output = '\n'.join([i for i in (stdout, stderr) if i is not None])
|
||||
output = "\n".join([i for i in (stdout, stderr) if i is not None])
|
||||
if process.returncode != 0:
|
||||
raise RuntimeError(output)
|
||||
else:
|
||||
|
@ -318,19 +316,19 @@ def setup(app: Sphinx) -> None:
|
|||
app : sphinx.application.Sphinx
|
||||
The application object representing the Sphinx process.
|
||||
"""
|
||||
first_run = not (CURR_PATH / '_FIRST_RUN.flag').exists()
|
||||
first_run = not (CURR_PATH / "_FIRST_RUN.flag").exists()
|
||||
if first_run and RTD:
|
||||
(CURR_PATH / '_FIRST_RUN.flag').touch()
|
||||
(CURR_PATH / "_FIRST_RUN.flag").touch()
|
||||
if C_API:
|
||||
app.connect("builder-inited", generate_doxygen_xml)
|
||||
else:
|
||||
app.add_directive('doxygenfile', IgnoredDirective)
|
||||
app.add_directive("doxygenfile", IgnoredDirective)
|
||||
if RTD: # build R docs only on Read the Docs site
|
||||
if first_run:
|
||||
app.connect("builder-inited", generate_r_docs)
|
||||
app.connect("build-finished",
|
||||
lambda app, _: copytree(CURR_PATH.parent / "lightgbm_r" / "docs",
|
||||
Path(app.outdir) / "R"))
|
||||
app.connect(
|
||||
"build-finished", lambda app, _: copytree(CURR_PATH.parent / "lightgbm_r" / "docs", Path(app.outdir) / "R")
|
||||
)
|
||||
app.add_transform(InternalRefTransform)
|
||||
add_js_file = getattr(app, 'add_js_file', False) or app.add_javascript
|
||||
add_js_file = getattr(app, "add_js_file", False) or app.add_javascript
|
||||
add_js_file("js/script.js")
|
||||
|
|
|
@ -25,7 +25,7 @@ def check_dependencies(objdump_string: str) -> None:
|
|||
objdump_string : str
|
||||
The dynamic symbol table entries of the file (result of `objdump -T` command).
|
||||
"""
|
||||
GLIBC_version = re.compile(r'0{16}[ \(\t]+GLIBC_(\d{1,2})[.](\d{1,3})[.]?\d{,3}[ \)\t]+')
|
||||
GLIBC_version = re.compile(r"0{16}[ \(\t]+GLIBC_(\d{1,2})[.](\d{1,3})[.]?\d{,3}[ \)\t]+")
|
||||
versions = GLIBC_version.findall(objdump_string)
|
||||
assert len(versions) > 1
|
||||
for major, minor in versions:
|
||||
|
@ -33,16 +33,16 @@ def check_dependencies(objdump_string: str) -> None:
|
|||
assert int(major) <= 2, error_msg
|
||||
assert int(minor) <= 28, error_msg
|
||||
|
||||
GLIBCXX_version = re.compile(r'0{16}[ \(\t]+GLIBCXX_(\d{1,2})[.](\d{1,2})[.]?(\d{,3})[ \)\t]+')
|
||||
GLIBCXX_version = re.compile(r"0{16}[ \(\t]+GLIBCXX_(\d{1,2})[.](\d{1,2})[.]?(\d{,3})[ \)\t]+")
|
||||
versions = GLIBCXX_version.findall(objdump_string)
|
||||
assert len(versions) > 1
|
||||
for major, minor, patch in versions:
|
||||
error_msg = f"found unexpected GLIBCXX version: '{major}.{minor}.{patch}'"
|
||||
assert int(major) == 3, error_msg
|
||||
assert int(minor) == 4, error_msg
|
||||
assert patch == '' or int(patch) <= 22, error_msg
|
||||
assert patch == "" or int(patch) <= 22, error_msg
|
||||
|
||||
GOMP_version = re.compile(r'0{16}[ \(\t]+G?OMP_(\d{1,2})[.](\d{1,2})[.]?\d{,3}[ \)\t]+')
|
||||
GOMP_version = re.compile(r"0{16}[ \(\t]+G?OMP_(\d{1,2})[.](\d{1,2})[.]?\d{,3}[ \)\t]+")
|
||||
versions = GOMP_version.findall(objdump_string)
|
||||
assert len(versions) > 1
|
||||
for major, minor in versions:
|
||||
|
@ -52,4 +52,4 @@ def check_dependencies(objdump_string: str) -> None:
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
check_dependencies(Path(sys.argv[1]).read_text(encoding='utf-8'))
|
||||
check_dependencies(Path(sys.argv[1]).read_text(encoding="utf-8"))
|
||||
|
|
|
@ -12,9 +12,7 @@ from pathlib import Path
|
|||
from typing import Dict, List, Tuple
|
||||
|
||||
|
||||
def get_parameter_infos(
|
||||
config_hpp: Path
|
||||
) -> Tuple[List[Tuple[str, int]], List[List[Dict[str, List]]]]:
|
||||
def get_parameter_infos(config_hpp: Path) -> Tuple[List[Tuple[str, int]], List[List[Dict[str, List]]]]:
|
||||
"""Parse config header file.
|
||||
|
||||
Parameters
|
||||
|
@ -44,7 +42,7 @@ def get_parameter_infos(
|
|||
cur_key = line.split("region")[1].strip()
|
||||
keys.append((cur_key, key_lvl))
|
||||
member_infos.append([])
|
||||
elif '#pragma endregion' in line:
|
||||
elif "#pragma endregion" in line:
|
||||
key_lvl -= 1
|
||||
if cur_key is not None:
|
||||
cur_key = None
|
||||
|
@ -87,9 +85,7 @@ def get_parameter_infos(
|
|||
return keys, member_infos
|
||||
|
||||
|
||||
def get_names(
|
||||
infos: List[List[Dict[str, List]]]
|
||||
) -> List[str]:
|
||||
def get_names(infos: List[List[Dict[str, List]]]) -> List[str]:
|
||||
"""Get names of all parameters.
|
||||
|
||||
Parameters
|
||||
|
@ -109,9 +105,7 @@ def get_names(
|
|||
return names
|
||||
|
||||
|
||||
def get_alias(
|
||||
infos: List[List[Dict[str, List]]]
|
||||
) -> List[Tuple[str, str]]:
|
||||
def get_alias(infos: List[List[Dict[str, List]]]) -> List[Tuple[str, str]]:
|
||||
"""Get aliases of all parameters.
|
||||
|
||||
Parameters
|
||||
|
@ -129,16 +123,13 @@ def get_alias(
|
|||
for y in x:
|
||||
if "alias" in y:
|
||||
name = y["name"][0]
|
||||
alias = y["alias"][0].split(',')
|
||||
alias = y["alias"][0].split(",")
|
||||
for name2 in alias:
|
||||
pairs.append((name2.strip(), name))
|
||||
return pairs
|
||||
|
||||
|
||||
def parse_check(
|
||||
check: str,
|
||||
reverse: bool = False
|
||||
) -> Tuple[str, str]:
|
||||
def parse_check(check: str, reverse: bool = False) -> Tuple[str, str]:
|
||||
"""Parse the constraint.
|
||||
|
||||
Parameters
|
||||
|
@ -160,17 +151,13 @@ def parse_check(
|
|||
idx = 2
|
||||
float(check[idx:])
|
||||
if reverse:
|
||||
reversed_sign = {'<': '>', '>': '<', '<=': '>=', '>=': '<='}
|
||||
reversed_sign = {"<": ">", ">": "<", "<=": ">=", ">=": "<="}
|
||||
return check[idx:], reversed_sign[check[:idx]]
|
||||
else:
|
||||
return check[idx:], check[:idx]
|
||||
|
||||
|
||||
def set_one_var_from_string(
|
||||
name: str,
|
||||
param_type: str,
|
||||
checks: List[str]
|
||||
) -> str:
|
||||
def set_one_var_from_string(name: str, param_type: str, checks: List[str]) -> str:
|
||||
"""Construct code for auto config file for one param value.
|
||||
|
||||
Parameters
|
||||
|
@ -209,9 +196,7 @@ def set_one_var_from_string(
|
|||
|
||||
|
||||
def gen_parameter_description(
|
||||
sections: List[Tuple[str, int]],
|
||||
descriptions: List[List[Dict[str, List]]],
|
||||
params_rst: Path
|
||||
sections: List[Tuple[str, int]], descriptions: List[List[Dict[str, List]]], params_rst: Path
|
||||
) -> None:
|
||||
"""Write descriptions of parameters to the documentation file.
|
||||
|
||||
|
@ -225,58 +210,57 @@ def gen_parameter_description(
|
|||
Path to the file with parameters documentation.
|
||||
"""
|
||||
params_to_write = []
|
||||
lvl_mapper = {1: '-', 2: '~'}
|
||||
lvl_mapper = {1: "-", 2: "~"}
|
||||
for (section_name, section_lvl), section_params in zip(sections, descriptions):
|
||||
heading_sign = lvl_mapper[section_lvl]
|
||||
params_to_write.append(f'{section_name}\n{heading_sign * len(section_name)}')
|
||||
params_to_write.append(f"{section_name}\n{heading_sign * len(section_name)}")
|
||||
for param_desc in section_params:
|
||||
name = param_desc['name'][0]
|
||||
default_raw = param_desc['default'][0]
|
||||
name = param_desc["name"][0]
|
||||
default_raw = param_desc["default"][0]
|
||||
default = default_raw.strip('"') if len(default_raw.strip('"')) > 0 else default_raw
|
||||
param_type = param_desc.get('type', param_desc['inner_type'])[0].split(':')[-1].split('<')[-1].strip('>')
|
||||
options = param_desc.get('options', [])
|
||||
param_type = param_desc.get("type", param_desc["inner_type"])[0].split(":")[-1].split("<")[-1].strip(">")
|
||||
options = param_desc.get("options", [])
|
||||
if len(options) > 0:
|
||||
opts = '``, ``'.join([x.strip() for x in options[0].split(',')])
|
||||
options_str = f', options: ``{opts}``'
|
||||
opts = "``, ``".join([x.strip() for x in options[0].split(",")])
|
||||
options_str = f", options: ``{opts}``"
|
||||
else:
|
||||
options_str = ''
|
||||
aliases = param_desc.get('alias', [])
|
||||
options_str = ""
|
||||
aliases = param_desc.get("alias", [])
|
||||
if len(aliases) > 0:
|
||||
aliases_joined = '``, ``'.join([x.strip() for x in aliases[0].split(',')])
|
||||
aliases_str = f', aliases: ``{aliases_joined}``'
|
||||
aliases_joined = "``, ``".join([x.strip() for x in aliases[0].split(",")])
|
||||
aliases_str = f", aliases: ``{aliases_joined}``"
|
||||
else:
|
||||
aliases_str = ''
|
||||
checks = sorted(param_desc.get('check', []))
|
||||
aliases_str = ""
|
||||
checks = sorted(param_desc.get("check", []))
|
||||
checks_len = len(checks)
|
||||
if checks_len > 1:
|
||||
number1, sign1 = parse_check(checks[0])
|
||||
number2, sign2 = parse_check(checks[1], reverse=True)
|
||||
checks_str = f', constraints: ``{number2} {sign2} {name} {sign1} {number1}``'
|
||||
checks_str = f", constraints: ``{number2} {sign2} {name} {sign1} {number1}``"
|
||||
elif checks_len == 1:
|
||||
number, sign = parse_check(checks[0])
|
||||
checks_str = f', constraints: ``{name} {sign} {number}``'
|
||||
checks_str = f", constraints: ``{name} {sign} {number}``"
|
||||
else:
|
||||
checks_str = ''
|
||||
checks_str = ""
|
||||
main_desc = f'- ``{name}`` :raw-html:`<a id="{name}" title="Permalink to this parameter" href="#{name}">🔗︎</a>`, default = ``{default}``, type = {param_type}{options_str}{aliases_str}{checks_str}'
|
||||
params_to_write.append(main_desc)
|
||||
params_to_write.extend([f"{' ' * 3 * int(desc[0][-1])}- {desc[1]}" for desc in param_desc['desc']])
|
||||
params_to_write.extend([f"{' ' * 3 * int(desc[0][-1])}- {desc[1]}" for desc in param_desc["desc"]])
|
||||
|
||||
with open(params_rst) as original_params_file:
|
||||
all_lines = original_params_file.read()
|
||||
before, start_sep, _ = all_lines.partition('.. start params list\n\n')
|
||||
_, end_sep, after = all_lines.partition('\n\n.. end params list')
|
||||
before, start_sep, _ = all_lines.partition(".. start params list\n\n")
|
||||
_, end_sep, after = all_lines.partition("\n\n.. end params list")
|
||||
|
||||
with open(params_rst, "w") as new_params_file:
|
||||
new_params_file.write(before)
|
||||
new_params_file.write(start_sep)
|
||||
new_params_file.write('\n\n'.join(params_to_write))
|
||||
new_params_file.write("\n\n".join(params_to_write))
|
||||
new_params_file.write(end_sep)
|
||||
new_params_file.write(after)
|
||||
|
||||
|
||||
def gen_parameter_code(
|
||||
config_hpp: Path,
|
||||
config_out_cpp: Path
|
||||
config_hpp: Path, config_out_cpp: Path
|
||||
) -> Tuple[List[Tuple[str, int]], List[List[Dict[str, List]]]]:
|
||||
"""Generate auto config file.
|
||||
|
||||
|
@ -367,7 +351,7 @@ def gen_parameter_code(
|
|||
if names_with_aliases[name]:
|
||||
str_to_write += '{"' + '", "'.join(names_with_aliases[name]) + '"}},'
|
||||
else:
|
||||
str_to_write += '{}},'
|
||||
str_to_write += "{}},"
|
||||
str_to_write += """
|
||||
});
|
||||
return map;
|
||||
|
@ -376,22 +360,22 @@ def gen_parameter_code(
|
|||
"""
|
||||
str_to_write += """const std::unordered_map<std::string, std::string>& Config::ParameterTypes() {
|
||||
static std::unordered_map<std::string, std::string> map({"""
|
||||
int_t_pat = re.compile(r'int\d+_t')
|
||||
int_t_pat = re.compile(r"int\d+_t")
|
||||
# the following are stored as comma separated strings but are arrays in the wrappers
|
||||
overrides = {
|
||||
'categorical_feature': 'vector<int>',
|
||||
'ignore_column': 'vector<int>',
|
||||
'interaction_constraints': 'vector<vector<int>>',
|
||||
"categorical_feature": "vector<int>",
|
||||
"ignore_column": "vector<int>",
|
||||
"interaction_constraints": "vector<vector<int>>",
|
||||
}
|
||||
for x in infos:
|
||||
for y in x:
|
||||
name = y["name"][0]
|
||||
if name == 'task':
|
||||
if name == "task":
|
||||
continue
|
||||
if name in overrides:
|
||||
param_type = overrides[name]
|
||||
else:
|
||||
param_type = int_t_pat.sub('int', y["inner_type"][0]).replace('std::', '')
|
||||
param_type = int_t_pat.sub("int", y["inner_type"][0]).replace("std::", "")
|
||||
str_to_write += '\n {"' + name + '", "' + param_type + '"},'
|
||||
str_to_write += """
|
||||
});
|
||||
|
@ -409,8 +393,8 @@ def gen_parameter_code(
|
|||
|
||||
if __name__ == "__main__":
|
||||
current_dir = Path(__file__).absolute().parent
|
||||
config_hpp = current_dir.parent / 'include' / 'LightGBM' / 'config.h'
|
||||
config_out_cpp = current_dir.parent / 'src' / 'io' / 'config_auto.cpp'
|
||||
params_rst = current_dir.parent / 'docs' / 'Parameters.rst'
|
||||
config_hpp = current_dir.parent / "include" / "LightGBM" / "config.h"
|
||||
config_out_cpp = current_dir.parent / "src" / "io" / "config_auto.cpp"
|
||||
params_rst = current_dir.parent / "docs" / "Parameters.rst"
|
||||
sections, descriptions = gen_parameter_code(config_hpp, config_out_cpp)
|
||||
gen_parameter_description(sections, descriptions, params_rst)
|
||||
|
|
|
@ -95,11 +95,29 @@ ignore_missing_imports = true
|
|||
exclude = [
|
||||
"build",
|
||||
"compile",
|
||||
"docs",
|
||||
"external_libs",
|
||||
"lightgbm-python",
|
||||
"setup.py"
|
||||
]
|
||||
line-length = 120
|
||||
|
||||
# this should be set to the oldest version of python LightGBM supports
|
||||
target-version = "py37"
|
||||
|
||||
[tool.ruff.format]
|
||||
docstring-code-format = false
|
||||
exclude = [
|
||||
"build/*.py",
|
||||
"compile/*.py",
|
||||
"examples/*.py",
|
||||
"external_libs/*.py",
|
||||
"lightgbm-python/*.py",
|
||||
"python-package/*.py",
|
||||
"tests/*.py"
|
||||
]
|
||||
indent-style = "space"
|
||||
quote-style = "double"
|
||||
|
||||
[tool.ruff.lint]
|
||||
ignore = [
|
||||
# (pydocstyle) Missing docstring in magic method
|
||||
"D105",
|
||||
|
@ -125,10 +143,13 @@ select = [
|
|||
"T",
|
||||
]
|
||||
|
||||
# this should be set to the oldest version of python LightGBM supports
|
||||
target-version = "py37"
|
||||
|
||||
[tool.ruff.per-file-ignores]
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"docs/conf.py" = [
|
||||
# (flake8-bugbear) raise exceptions with "raise ... from errr"
|
||||
"B904",
|
||||
# (flake8-print) flake8-print
|
||||
"T"
|
||||
]
|
||||
"examples/*" = [
|
||||
# pydocstyle
|
||||
"D",
|
||||
|
@ -144,6 +165,5 @@ target-version = "py37"
|
|||
"T"
|
||||
]
|
||||
|
||||
[tool.ruff.pydocstyle]
|
||||
|
||||
[tool.ruff.lint.pydocstyle]
|
||||
convention = "numpy"
|
||||
|
|
Загрузка…
Ссылка в новой задаче