Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Tests

on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: pytest (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]

steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-py${{ matrix.python-version }}-pip-${{ hashFiles('pyproject.toml') }}
restore-keys: |
${{ runner.os }}-py${{ matrix.python-version }}-pip-

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install pytest pytest-cov

- name: Run pytest
run: pytest -v --tb=short --cov=src/glinker --cov-report=term-missing

lint:
name: ruff
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install ruff
run: pip install ruff

- name: ruff check
run: ruff check src/glinker

- name: ruff format --check
run: ruff format --check src/glinker
96 changes: 96 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ dependencies = [
"pydantic>=2.0.0",
"pyyaml>=6.0.0",
"tqdm>=4.65.0",
"rapidfuzz>=3.0.0",
]

[project.optional-dependencies]
Expand Down Expand Up @@ -72,6 +73,101 @@ target-version = ["py310", "py311"]
[tool.ruff]
line-length = 100
target-version = "py310"
src = ["src"]

[tool.ruff.lint]
select = [
"F", # Pyflakes
"E", # pycodestyle errors
"W", # pycodestyle warnings
"I", # isort
"D", # pydocstyle
"UP", # pyupgrade
"B", # bugbear
"SIM", # simplify
"ARG", # unused arguments
"T20", # print statements
"C4", # comprehensions
"EM", # errmsg
"PL", # Pylint
"RUF" # Ruff-specific rules
]

ignore = [
"D100", # Missing docstring in public module
"D101", # Missing docstring in public class
"D102", # Missing docstring in public method
"D103", # Missing docstring in public function
"D104", # Missing docstring in public package
"D105", # Missing docstring in magic method
"D107", # Missing docstring in `__init__`
"D200", # One-line docstring should fit on one line
"D205", # Blank line required between summary and description
"D212", # Multi-line docstring summary should start at the first line
"D400", # First line should end with a period
"D401", # First line should be in imperative mood
"D417", # Missing argument descriptions
"RUF012", # Mutable class attributes should be annotated
"PLR0913",# Too many arguments
"PLR0912",# Too many branches
"PLR0915",# Too many statements
"PLR2004",# Magic value used in comparison
"PLW2901",# Loop variable overwritten
"B006", # Mutable defaults
"B027", # Empty method without abstract decorator
"B904", # Raise without from inside except
"S101", # Use of `assert` detected
"SIM102", # Collapsible if statements
"SIM105", # Use contextlib.suppress instead of try-except-pass
"SIM108", # Use ternary operator
"UP035", # Deprecated typing imports
"UP006", # Deprecated typing imports
"EM101", # Exception message formatting
"EM102", # Exception message formatting
"ARG002", # Unused method arguments
"B905", # zip() without explicit strict= parameter
"E402", # Module level import not at top (for conditional imports)
"E501", # Line too long (handled by formatter)
"E722", # Bare except (intentional for fallback logic)
"E741", # Ambiguous variable name (short names in comprehensions)
"PLC0206",# Extracting value from dictionary without .items()
"PLC0415",# Import should be at top-level (for dynamic imports)
"T201", # Print statements (used for debugging)
]

unfixable = [
"T201", # Print statements
"T203", # pprint statements
]

dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[tool.ruff.lint.per-file-ignores]
"__init__.py" = [
"F401", # Unused imports in __init__.py are often intentional
"F403", # Star imports in __init__.py
]
"tests/**/*.py" = [
"D", # No docstring requirements in tests
"ARG", # Unused arguments are common in test fixtures
"PLR2004",# Magic values are fine in tests
"S101", # Assert is expected in tests
]

[tool.ruff.lint.isort]
length-sort = true
length-sort-straight = true
combine-as-imports = true
known-first-party = ["glinker"]

[tool.ruff.lint.pydocstyle]
convention = "google"

[tool.ruff.lint.pylint]
max-args = 20
max-branches = 15
max-returns = 8
max-statements = 60

[tool.pytest.ini_options]
testpaths = ["tests"]
Expand Down
61 changes: 30 additions & 31 deletions src/glinker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,44 @@
from glinker.l2 import processor as _l2_processor
from glinker.l3 import processor as _l3_processor
from glinker.l4 import processor as _l4_processor

from glinker.core import (
BaseConfig,
PipeNode,
BaseInput,
BaseConfig,
BaseOutput,
DAGExecutor,
DAGPipeline,
InputConfig,
PipeContext,
OutputConfig,
BaseComponent,
BaseProcessor,
ProcessorRegistry,
processor_registry,
ConfigBuilder,
FieldResolver,
ReshapeConfig,
ProcessorFactory,
ProcessorRegistry,
load_yaml,
InputConfig,
OutputConfig,
ReshapeConfig,
PipeNode,
PipeContext,
FieldResolver,
DAGPipeline,
DAGExecutor,
ConfigBuilder,
processor_registry,
)

__all__ = [
'BaseConfig',
'BaseInput',
'BaseOutput',
'BaseComponent',
'BaseProcessor',
'ProcessorRegistry',
'processor_registry',
'ProcessorFactory',
'load_yaml',
'InputConfig',
'OutputConfig',
'ReshapeConfig',
'PipeNode',
'PipeContext',
'FieldResolver',
'DAGPipeline',
'DAGExecutor',
'ConfigBuilder',
"BaseComponent",
"BaseConfig",
"BaseInput",
"BaseOutput",
"BaseProcessor",
"ConfigBuilder",
"DAGExecutor",
"DAGPipeline",
"FieldResolver",
"InputConfig",
"OutputConfig",
"PipeContext",
"PipeNode",
"ProcessorFactory",
"ProcessorRegistry",
"ReshapeConfig",
"load_yaml",
"processor_registry",
]
83 changes: 37 additions & 46 deletions src/glinker/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,56 +1,47 @@
from .dag import (
PipeNode,
DAGExecutor,
DAGPipeline,
InputConfig,
PipeContext,
OutputConfig,
FieldResolver,
ReshapeConfig,
)
from .base import (
BaseConfig,
InputT,
ConfigT,
OutputT,
BaseInput,
BaseConfig,
BaseOutput,
BaseComponent,
BaseProcessor,
ConfigT,
InputT,
OutputT
)
from .registry import (
ProcessorRegistry,
processor_registry
)
from .factory import ProcessorFactory, load_yaml

from .dag import (
InputConfig,
OutputConfig,
ReshapeConfig,
PipeNode,
PipeContext,
FieldResolver,
DAGPipeline,
DAGExecutor
)

from .builders import ConfigBuilder
from .registry import ProcessorRegistry, processor_registry

__all__ = [
'BaseConfig',
'BaseInput',
'BaseOutput',
'BaseComponent',
'BaseProcessor',
'ConfigT',
'InputT',
'OutputT',

'ProcessorRegistry',
'processor_registry',

'ProcessorFactory',
'load_yaml',

'InputConfig',
'OutputConfig',
'ReshapeConfig',
'PipeNode',
'PipeContext',
'FieldResolver',
'DAGPipeline',
'DAGExecutor',

'ConfigBuilder',
]
"BaseComponent",
"BaseConfig",
"BaseInput",
"BaseOutput",
"BaseProcessor",
"ConfigBuilder",
"ConfigT",
"DAGExecutor",
"DAGPipeline",
"FieldResolver",
"InputConfig",
"InputT",
"OutputConfig",
"OutputT",
"PipeContext",
"PipeNode",
"ProcessorFactory",
"ProcessorRegistry",
"ReshapeConfig",
"load_yaml",
"processor_registry",
]
Loading
Loading