From 83774ad79d12f5b13863d80316b9e1c5300f5ca7 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Thu, 17 Nov 2022 12:25:09 -0500 Subject: [PATCH 1/8] style: working ruff and mypy --- .github/workflows/test_and_deploy.yml | 4 +- .pre-commit-config.yaml | 49 +++++---- pyproject.toml | 146 ++++++++++++++++++++++++++ setup.cfg | 95 ----------------- setup.py | 25 ++++- {useq => src/useq}/__init__.py | 0 {useq => src/useq}/_base_model.py | 16 +-- {useq => src/useq}/_channel.py | 0 {useq => src/useq}/_mda_event.py | 0 {useq => src/useq}/_mda_sequence.py | 6 +- {useq => src/useq}/_position.py | 0 {useq => src/useq}/_time.py | 0 {useq => src/useq}/_utils.py | 0 {useq => src/useq}/_z.py | 10 +- tests/test_json.py | 22 ++-- tests/test_yaml.py | 22 ++-- 16 files changed, 245 insertions(+), 150 deletions(-) create mode 100644 pyproject.toml delete mode 100644 setup.cfg rename {useq => src/useq}/__init__.py (100%) rename {useq => src/useq}/_base_model.py (91%) rename {useq => src/useq}/_channel.py (100%) rename {useq => src/useq}/_mda_event.py (100%) rename {useq => src/useq}/_mda_sequence.py (98%) rename {useq => src/useq}/_position.py (100%) rename {useq => src/useq}/_time.py (100%) rename {useq => src/useq}/_utils.py (100%) rename {useq => src/useq}/_z.py (88%) diff --git a/.github/workflows/test_and_deploy.yml b/.github/workflows/test_and_deploy.yml index 650e70e5..e18e94f1 100644 --- a/.github/workflows/test_and_deploy.yml +++ b/.github/workflows/test_and_deploy.yml @@ -31,7 +31,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -e .[testing] + pip install -e .[test] - name: Test run: pytest -v --color=yes --cov-report=xml --cov=useq @@ -59,7 +59,7 @@ jobs: run: | python -m pip install --upgrade pip pip install -e pymmcore-plus-from-github[testing] - pip install -e .[testing] + pip install -e .[test] - name: Install Micro-Manager run: python -m pymmcore_plus.install diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 760305dc..db71f3ca 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,34 +1,45 @@ +ci: + autoupdate_schedule: monthly + autofix_commit_msg: "style(pre-commit.ci): auto fixes [...]" + autoupdate_commit_msg: "ci(pre-commit.ci): autoupdate" + +default_install_hook_types: [pre-commit, commit-msg] + repos: + - repo: https://github.com/compilerla/conventional-pre-commit + rev: v1.3.0 + hooks: + - id: conventional-pre-commit + stages: [commit-msg] + - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.3.0 hooks: + - id: check-docstring-first - id: end-of-file-fixer - id: trailing-whitespace - - repo: https://github.com/PyCQA/autoflake - rev: v1.7.7 - hooks: - - id: autoflake - args: ["--in-place", "--remove-all-unused-imports"] - - repo: https://github.com/PyCQA/isort - rev: 5.10.1 - hooks: - - id: isort - - repo: https://github.com/asottile/pyupgrade - rev: v3.2.0 + + - repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.0.124 hooks: - - id: pyupgrade - args: ["--py3-plus", "--keep-runtime-typing"] + - id: ruff + args: [--fix] + - repo: https://github.com/psf/black rev: 22.10.0 hooks: - id: black - - repo: https://github.com/PyCQA/flake8 - rev: 5.0.4 + + - repo: https://github.com/abravalheri/validate-pyproject + rev: v0.10.1 hooks: - - id: flake8 - pass_filenames: true + - id: validate-pyproject + - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.982 + rev: v0.991 hooks: - id: mypy - additional_dependencies: [pydantic, types-PyYAML] + additional_dependencies: + - types-PyYAML + - pydantic + files: "^src/" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..2ccf6ed7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,146 @@ +# https://peps.python.org/pep-0517/ +[build-system] +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +# https://peps.python.org/pep-0621/ +[project] +name = "useq-schema" +description = "Schema for multi-dimensional microscopy experiments" +readme = "README.md" +keywords = ["microscopy", "schema"] +requires-python = ">=3.8" +license = { text = "BSD 3-Clause License" } +authors = [{ email = "talley.lambert@gmail.com", name = "Talley Lambert" }] +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Medical Science Apps.", + "Topic :: Scientific/Engineering :: Image Processing", + "Topic :: Software Development", +] +dynamic = ["version"] +dependencies = [] + +# extras +# https://peps.python.org/pep-0621/#dependencies-optional-dependencies +[project.optional-dependencies] +yaml = ["PyYAML"] +test = ["pytest>=6.0", "pytest-cov"] +dev = [ + "black", + "ipython", + "mypy", + "pdbpp", + "pre-commit", + "pytest-cov", + "pytest", + "rich", + "ruff", + "PyYaml" +] + +[project.urls] +Source = "https://github.com/pymmcore-plus/useq-schema" +Tracker = "https://github.com/pymmcore-plus/useq-schema/issues" + +# same as console_scripts entry point +# [project.scripts] +# spam-cli = "spam:main_cli" + +# Entry points +# https://peps.python.org/pep-0621/#entry-points +# [project.entry-points."spam.magical"] +# tomatoes = "spam:main_tomatoes" + +# https://hatch.pypa.io/latest/config/metadata/ +[tool.hatch.version] +source = "vcs" + +# https://hatch.pypa.io/latest/config/build/#file-selection +# [tool.hatch.build.targets.sdist] +# include = ["/src", "/tests"] + + +# https://github.com/charliermarsh/ruff +[tool.ruff] +line-length = 88 +target-version = "py38" +select = [ + "E", # style errors + "F", # flakes + "D", # pydocstyle + "I001", # isort + "U", # pyupgrade + # "N", # pep8-naming + # "S", # bandit + "C", # comprehensions + "B", # bugbear + "A001", # Variable shadowing a python builtin + "RUF", # ruff-specific rules + "M001", # Unused noqa directive +] +extend-ignore = [ + "D100", # Missing docstring in public module + "D107", # Missing docstring in __init__ + "D203", # 1 blank line required before class docstring + "D212", # Multi-line docstring summary should start at the first line + "D213", # Multi-line docstring summary should start at the second line + "D413", # Missing blank line after last section + "D416", # Section name should end with a colon +] + +[tool.ruff.per-file-ignores] +"tests/*.py" = ["D"] + +# https://docs.pytest.org/en/6.2.x/customize.html +[tool.pytest.ini_options] +minversion = "6.0" +testpaths = ["tests"] +filterwarnings = ["error"] + +# https://mypy.readthedocs.io/en/stable/config_file.html +[tool.mypy] +files = "src/**/" +strict = true +disallow_any_generics = false +disallow_subclassing_any = false +show_error_codes = true +pretty = true + + +# https://coverage.readthedocs.io/en/6.4/config.html +[tool.coverage.report] +exclude_lines = [ + "pragma: no cover", + "if TYPE_CHECKING:", + "@overload", + "except ImportError", +] + +# https://github.com/mgedmin/check-manifest#configuration +[tool.check-manifest] +ignore = [ + ".github_changelog_generator", + ".pre-commit-config.yaml", + ".ruff_cache/**/*", + "tests/**/*", + "tox.ini", +] + +# https://python-semantic-release.readthedocs.io/en/latest/configuration.html +[tool.semantic_release] +version_source = "tag_only" +branch = "main" +changelog_sections = "feature,fix,breaking,documentation,performance,chore,:boom:,:sparkles:,:children_crossing:,:lipstick:,:iphone:,:egg:,:chart_with_upwards_trend:,:ambulance:,:lock:,:bug:,:zap:,:goal_net:,:alien:,:wheelchair:,:speech_balloon:,:mag:,:apple:,:penguin:,:checkered_flag:,:robot:,:green_apple:,Other" +# commit_parser=semantic_release.history.angular_parser +build_command = "pip install build && python -m build" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 1b8e51c6..00000000 --- a/setup.cfg +++ /dev/null @@ -1,95 +0,0 @@ -[metadata] -name = useq-schema -url = https://github.com/pymmcore-plus/useq-schema -download_url = https://github.com/pymmcore-plus/useq-schema -license = BSD 3-Clause -license_file = LICENSE -description = Schema for multi-dimensional microscopy experiments -long_description = file: README.md -long_description_content_type = text/markdown -author = Talley Lambert -author_email = talley.lambert@gmail.com -keywords = microscopy, schema -project_urls = - Source = https://github.com/pymmcore-plus/useq-schema - Tracker = https://github.com/pymmcore-plus/useq-schema/issues -classifiers = - Development Status :: 3 - Alpha - Intended Audience :: Developers - Intended Audience :: Science/Research - License :: OSI Approved :: BSD License - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Topic :: Scientific/Engineering - Topic :: Scientific/Engineering :: Medical Science Apps. - Topic :: Scientific/Engineering :: Image Processing - Topic :: Software Development - -[options] -zip_safe = False -packages = find: -python_requires = >=3.7 -setup_requires = - setuptools_scm -install_requires = - pydantic - numpy - - -[options.extras_require] -yaml = - PyYAML -testing = - pytest - pytest-cov - %(yaml)s -dev = - ipython - jedi<0.18.0 - black - flake8 - isort - mypy - pre-commit - %(testing)s - -[flake8] -exclude = docs,_version.py,.eggs,examples -max-line-length = 88 -docstring-convention = numpy -ignore = W503 - -[mypy] -plugins = pydantic.mypy - -files = useq, tests -warn_unused_configs = True -warn_unused_ignores = True -check_untyped_defs = True -follow_imports = silent -warn_redundant_casts = True -# disallow_any_generics = True -no_implicit_reexport = True -show_column_numbers = True -show_error_codes = True -ignore_missing_imports = True - -disallow_untyped_defs = True - -[pydantic-mypy] -init_forbid_extra = True -# init_typed = True -warn_required_dynamic_aliases = True -warn_untyped_fields = True - - -[isort] -profile = black -src_paths = useq - -[tool:pytest] -addopts = -v -W error diff --git a/setup.py b/setup.py index 89aaf7f5..1849a4e0 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,24 @@ -import setuptools +import sys -setuptools.setup(use_scm_version={"write_to": "useq/_version.py"}) +sys.stderr.write( + """ +=============================== +Unsupported installation method +=============================== +useq-schema does not support installation with `python setup.py install`. +Please use `python -m pip install .` instead. +""" +) +sys.exit(1) + + +# The below code will never execute, however GitHub is particularly +# picky about where it finds Python packaging metadata. +# See: https://github.com/github/feedback/discussions/6456 +# +# To be removed once GitHub catches up. + +setup( # noqa + name="useq-schema", + install_requires=[], +) diff --git a/useq/__init__.py b/src/useq/__init__.py similarity index 100% rename from useq/__init__.py rename to src/useq/__init__.py diff --git a/useq/_base_model.py b/src/useq/_base_model.py similarity index 91% rename from useq/_base_model.py rename to src/useq/_base_model.py index 4ceb9aa7..11e5d828 100644 --- a/useq/_base_model.py +++ b/src/useq/_base_model.py @@ -42,8 +42,8 @@ def __repr_args__(self) -> ReprArgs: if k in self.__fields__ and val != ( - self.__fields__[k].default_factory() # type: ignore - if self.__fields__[k].default_factory + factory() + if (factory := self.__fields__[k].default_factory) is not None else self.__fields__[k].default ) ] @@ -58,8 +58,8 @@ def __repr__(self) -> str: continue f = self.__fields__[k] default = ( - self.__fields__[k].default_factory() # type: ignore - if self.__fields__[k].default_factory + factory() + if (factory := self.__fields__[k].default_factory) is not None else self.__fields__[k].default ) if current != default: @@ -97,7 +97,7 @@ def parse_raw( return cls.parse_obj(obj) return super().parse_raw( b, - content_type=content_type, + content_type=content_type, # type: ignore encoding=encoding, proto=proto, # type: ignore allow_pickle=allow_pickle, @@ -131,7 +131,7 @@ def parse_file( return super().parse_file( path, - content_type=content_type, + content_type=content_type, # type: ignore encoding=encoding, proto=proto, # type: ignore allow_pickle=allow_pickle, @@ -140,8 +140,8 @@ def parse_file( def yaml( self, *, - include: Union[set, dict] = None, - exclude: Union[set, dict] = None, + include: Optional[Union[set, dict]] = None, + exclude: Optional[Union[set, dict]] = None, by_alias: bool = False, exclude_unset: bool = True, # pydantic has False by default exclude_defaults: bool = False, diff --git a/useq/_channel.py b/src/useq/_channel.py similarity index 100% rename from useq/_channel.py rename to src/useq/_channel.py diff --git a/useq/_mda_event.py b/src/useq/_mda_event.py similarity index 100% rename from useq/_mda_event.py rename to src/useq/_mda_event.py diff --git a/useq/_mda_sequence.py b/src/useq/_mda_sequence.py similarity index 98% rename from useq/_mda_sequence.py rename to src/useq/_mda_sequence.py index 350ffefb..20d5e53e 100644 --- a/useq/_mda_sequence.py +++ b/src/useq/_mda_sequence.py @@ -123,7 +123,7 @@ def validate_time_plan(cls, v: Any) -> Union[dict, NoT]: return {"phases": v} if isinstance(v, (tuple, list)) else v or NoT() @validator("stage_positions", pre=True) - def validate_positions(cls, v: Any) -> list: + def validate_positions(cls, v: Any) -> Any: if isinstance(v, np.ndarray): if v.ndim == 1: return [v] @@ -160,14 +160,14 @@ def validate_mda(cls, values: Dict[str, Any]) -> Dict[str, Any]: def __eq__(self, other: Any) -> bool: if isinstance(other, MDASequence): - return self.dict(exclude={"uid"}) == other.dict(exclude={"uid"}) + return bool(self.dict(exclude={"uid"}) == other.dict(exclude={"uid"})) else: return False @staticmethod def _check_order( order: str, - z_plan: AnyZPlan = None, + z_plan: Optional[AnyZPlan] = None, stage_positions: Sequence[Position] = (), channels: Sequence[Channel] = (), ) -> str: diff --git a/useq/_position.py b/src/useq/_position.py similarity index 100% rename from useq/_position.py rename to src/useq/_position.py diff --git a/useq/_time.py b/src/useq/_time.py similarity index 100% rename from useq/_time.py rename to src/useq/_time.py diff --git a/useq/_utils.py b/src/useq/_utils.py similarity index 100% rename from useq/_utils.py rename to src/useq/_utils.py diff --git a/useq/_z.py b/src/useq/_z.py similarity index 88% rename from useq/_z.py rename to src/useq/_z.py index 72bd26a7..d6cb8fb9 100644 --- a/useq/_z.py +++ b/src/useq/_z.py @@ -34,7 +34,7 @@ class ZTopBottom(ZPlan): go_up: bool = True def positions(self) -> Sequence[float]: - return np.arange(self.bottom, self.top + self.step, self.step) + return np.arange(self.bottom, self.top + self.step, self.step) # type: ignore @property def is_relative(self) -> bool: @@ -52,7 +52,9 @@ class ZRangeAround(ZPlan): go_up: bool = True def positions(self) -> Sequence[float]: - return np.arange(-self.range / 2, self.range / 2 + self.step, self.step) + return np.arange( # type: ignore + -self.range / 2, self.range / 2 + self.step, self.step + ) class ZAboveBelow(ZPlan): @@ -64,7 +66,9 @@ class ZAboveBelow(ZPlan): go_up: bool = True def positions(self) -> Sequence[float]: - return np.arange(-abs(self.below), +abs(self.above) + self.step, self.step) + return np.arange( # type: ignore + -abs(self.below), +abs(self.above) + self.step, self.step + ) class ZRelativePositions(ZPlan): diff --git a/tests/test_json.py b/tests/test_json.py index 39af88d2..f126182f 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -10,20 +10,24 @@ metadata={"some info": "something"}, stage_positions=[ (10, 20), - dict( - x=10, y=20, z=50, name="test_name", z_plan=dict(above=10, below=0, step=1) - ), + { + "x": 10, + "y": 20, + "z": 50, + "name": "test_name", + "z_plan": {"above": 10, "below": 0, "step": 1}, + }, ], channels=[ - dict(config="Cy5", exposure=50), - dict(config="FITC", exposure=100.0), - dict(config="DAPI", do_stack=False, acquire_every=3), + {"config": "Cy5", "exposure": 50}, + {"config": "FITC", "exposure": 100.0}, + {"config": "DAPI", "do_stack": False, "acquire_every": 3}, ], time_plan=[ - dict(interval=3, loops=3), - dict(duration={"minutes": 40}, interval=10), + {"interval": 3, "loops": 3}, + {"duration": {"minutes": 40}, "interval": 10}, ], - z_plan=dict(range=1.0, step=0.5), + z_plan={"range": 1.0, "step": 0.5}, ) diff --git a/tests/test_yaml.py b/tests/test_yaml.py index a927b77f..8fe56c0d 100644 --- a/tests/test_yaml.py +++ b/tests/test_yaml.py @@ -42,20 +42,24 @@ metadata={"some info": "something"}, stage_positions=[ (10, 20), - dict( - x=10, y=20, z=50, name="test_name", z_plan=dict(above=10, below=0, step=1) - ), + { + "x": 10, + "y": 20, + "z": 50, + "name": "test_name", + "z_plan": {"above": 10, "below": 0, "step": 1}, + }, ], channels=[ - dict(config="Cy5", exposure=50), - dict(config="FITC", exposure=100.0), - dict(config="DAPI", do_stack=False, acquire_every=3), + {"config": "Cy5", "exposure": 50}, + {"config": "FITC", "exposure": 100.0}, + {"config": "DAPI", "do_stack": False, "acquire_every": 3}, ], time_plan=[ - dict(interval=3, loops=3), - dict(duration={"minutes": 40}, interval=10), + {"interval": 3, "loops": 3}, + {"duration": {"minutes": 40}, "interval": 10}, ], - z_plan=dict(range=1.0, step=0.5), + z_plan={"range": 1.0, "step": 0.5}, ) From e2d4a4ea2ae504ee40bc1b776a624f2970b708d3 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Thu, 17 Nov 2022 12:30:03 -0500 Subject: [PATCH 2/8] chore: cleanup --- .github/dependabot.yml | 10 +++++++ .github/workflows/test_and_deploy.yml | 43 +++++++++++++++++++-------- pyproject.toml | 8 ----- 3 files changed, 40 insertions(+), 21 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..96505a93 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + commit-message: + prefix: "ci(dependabot):" diff --git a/.github/workflows/test_and_deploy.yml b/.github/workflows/test_and_deploy.yml index e18e94f1..f507a338 100644 --- a/.github/workflows/test_and_deploy.yml +++ b/.github/workflows/test_and_deploy.yml @@ -5,22 +5,35 @@ on: branches: - main tags: - - "v*" # Push events to matching v*, i.e. v1.0, v20.15.10 - pull_request: - branches: - - main + - "v*" + pull_request: {} workflow_dispatch: jobs: + check-manifest: + name: Check Manifest + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + - run: pip install check-manifest && check-manifest + test: name: ${{ matrix.platform }} (${{ matrix.python-version }}) runs-on: ${{ matrix.platform }} strategy: fail-fast: false matrix: - python-version: [3.7, 3.8, 3.9 ,"3.10"] + python-version: [3.7, 3.8, 3.9 ,"3.10", "3.11"] platform: [ubuntu-latest, macos-latest, windows-latest] steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.9.1 + with: + access_token: ${{ github.token }} + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} @@ -37,7 +50,6 @@ jobs: run: pytest -v --color=yes --cov-report=xml --cov=useq - name: Coverage - if: runner.os == 'Linux' uses: codecov/codecov-action@v1 test_pymmcore: @@ -81,16 +93,21 @@ jobs: with: python-version: "3.x" - - name: Install dependencies + - name: install run: | - python -m pip install --upgrade pip - pip install -U setuptools setuptools_scm wheel twine + git tag + pip install -U pip + pip install -U build twine + python -m build + twine check dist/* + ls -lh dist - name: Build and publish + run: twine upload dist/* env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.TWINE_API_KEY }} - run: | - git tag - python setup.py sdist bdist_wheel - twine upload dist/* + + - uses: softprops/action-gh-release@v1 + with: + generate_release_notes: true diff --git a/pyproject.toml b/pyproject.toml index 2ccf6ed7..4fc09a65 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -136,11 +136,3 @@ ignore = [ "tests/**/*", "tox.ini", ] - -# https://python-semantic-release.readthedocs.io/en/latest/configuration.html -[tool.semantic_release] -version_source = "tag_only" -branch = "main" -changelog_sections = "feature,fix,breaking,documentation,performance,chore,:boom:,:sparkles:,:children_crossing:,:lipstick:,:iphone:,:egg:,:chart_with_upwards_trend:,:ambulance:,:lock:,:bug:,:zap:,:goal_net:,:alien:,:wheelchair:,:speech_balloon:,:mag:,:apple:,:penguin:,:checkered_flag:,:robot:,:green_apple:,Other" -# commit_parser=semantic_release.history.angular_parser -build_command = "pip install build && python -m build" From e8c416fe6c11c91293d1af9bb2cefa862e0fdbb9 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Thu, 17 Nov 2022 12:32:20 -0500 Subject: [PATCH 3/8] fix: add deps --- pyproject.toml | 4 ++-- setup.py | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4fc09a65..6131e2ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ classifiers = [ "Topic :: Software Development", ] dynamic = ["version"] -dependencies = [] +dependencies = ["pydantic", "numpy"] # extras # https://peps.python.org/pep-0621/#dependencies-optional-dependencies @@ -46,7 +46,7 @@ dev = [ "pytest", "rich", "ruff", - "PyYaml" + "PyYaml", ] [project.urls] diff --git a/setup.py b/setup.py index 1849a4e0..3fe6ae37 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,4 @@ # # To be removed once GitHub catches up. -setup( # noqa - name="useq-schema", - install_requires=[], -) +setup(name="useq-schema", install_requires=["pydantic", "numpy"]) # noqa From 5a8f040be1303d5589250a3864081ef56c4d7c82 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Thu, 17 Nov 2022 12:33:28 -0500 Subject: [PATCH 4/8] fix: py37 --- pyproject.toml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6131e2ea..dceaa998 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ name = "useq-schema" description = "Schema for multi-dimensional microscopy experiments" readme = "README.md" keywords = ["microscopy", "schema"] -requires-python = ">=3.8" +requires-python = ">=3.7" license = { text = "BSD 3-Clause License" } authors = [{ email = "talley.lambert@gmail.com", name = "Talley Lambert" }] classifiers = [ @@ -20,9 +20,6 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Topic :: Scientific/Engineering", "Topic :: Scientific/Engineering :: Medical Science Apps.", "Topic :: Scientific/Engineering :: Image Processing", @@ -74,7 +71,7 @@ source = "vcs" # https://github.com/charliermarsh/ruff [tool.ruff] line-length = 88 -target-version = "py38" +target-version = "py37" select = [ "E", # style errors "F", # flakes From 3c2cc5f219578807afc2011ad4b5f7f6763d9d6b Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Thu, 17 Nov 2022 12:41:48 -0500 Subject: [PATCH 5/8] fix: build --- pyproject.toml | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index dceaa998..3793b779 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,23 +50,13 @@ dev = [ Source = "https://github.com/pymmcore-plus/useq-schema" Tracker = "https://github.com/pymmcore-plus/useq-schema/issues" -# same as console_scripts entry point -# [project.scripts] -# spam-cli = "spam:main_cli" - -# Entry points -# https://peps.python.org/pep-0621/#entry-points -# [project.entry-points."spam.magical"] -# tomatoes = "spam:main_tomatoes" - # https://hatch.pypa.io/latest/config/metadata/ [tool.hatch.version] source = "vcs" # https://hatch.pypa.io/latest/config/build/#file-selection -# [tool.hatch.build.targets.sdist] -# include = ["/src", "/tests"] - +[tool.hatch.build.targets.wheel] +packages = ["src/useq"] # https://github.com/charliermarsh/ruff [tool.ruff] @@ -132,4 +122,5 @@ ignore = [ ".ruff_cache/**/*", "tests/**/*", "tox.ini", + "setup.py" ] From d9771bb86d7b630cf4fb38c8d3e213d2baa9c550 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 17 Nov 2022 19:08:34 +0000 Subject: [PATCH 6/8] style(pre-commit.ci): auto fixes [...] --- tests/test_sequence.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_sequence.py b/tests/test_sequence.py index d5fa81da..02648003 100644 --- a/tests/test_sequence.py +++ b/tests/test_sequence.py @@ -4,7 +4,6 @@ import numpy as np import pytest from pydantic import BaseModel - from useq import ( Channel, MDAEvent, From ada4ce9899fe595f687a0ac34dc0c10de4cc5e65 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Thu, 17 Nov 2022 14:11:43 -0500 Subject: [PATCH 7/8] fix: add pyyaml to test --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3793b779..a2a60a15 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ dependencies = ["pydantic", "numpy"] # https://peps.python.org/pep-0621/#dependencies-optional-dependencies [project.optional-dependencies] yaml = ["PyYAML"] -test = ["pytest>=6.0", "pytest-cov"] +test = ["pytest>=6.0", "pytest-cov", "PyYAML"] dev = [ "black", "ipython", From 5301f9e06c77bfb85b5ab69cbca4299ab8cf2a94 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Thu, 17 Nov 2022 14:15:31 -0500 Subject: [PATCH 8/8] fix py37 --- src/useq/_base_model.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/useq/_base_model.py b/src/useq/_base_model.py index 11e5d828..8aab782c 100644 --- a/src/useq/_base_model.py +++ b/src/useq/_base_model.py @@ -42,8 +42,8 @@ def __repr_args__(self) -> ReprArgs: if k in self.__fields__ and val != ( - factory() - if (factory := self.__fields__[k].default_factory) is not None + self.__fields__[k].default_factory() # type: ignore + if self.__fields__[k].default_factory is not None else self.__fields__[k].default ) ] @@ -58,8 +58,8 @@ def __repr__(self) -> str: continue f = self.__fields__[k] default = ( - factory() - if (factory := self.__fields__[k].default_factory) is not None + self.__fields__[k].default_factory() # type: ignore + if self.__fields__[k].default_factory is not None else self.__fields__[k].default ) if current != default: