Skip to content

Add metaflow-functions OSS package#66

Merged
npow merged 66 commits into
mainfrom
npow/mff
Apr 14, 2026
Merged

Add metaflow-functions OSS package#66
npow merged 66 commits into
mainfrom
npow/mff

Conversation

@npow

@npow npow commented Mar 7, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

Nissan Pow and others added 30 commits March 6, 2026 07:54
Move metaflow-netflixext package into its own subdirectory to support
adding additional packages that can be independently published to PyPI.
Adds the metaflow-functions OSS package with support for avro/json
function types, memory/local/ray backends, and shared memory IPC.
ray is an install_requires dependency but was missing from
get_pinned_conda_libs, causing ModuleNotFoundError in conda
environments using the ray backend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add comprehensive unit tests for conda plugin functionality:
- File parsing (requirements.txt, conda.yml, pyproject.toml)
- Resolver tests (conda, pip, conda-lock, pylock-toml)
- Utility functions
- Environment creation and management
- Concurrent writes handling

Test results: 177/196 passing (90% pass rate)
- 18 CLI integration tests need environment configuration
- 1 test has plugin loading conflicts

These tests were developed internally at Netflix and provide
extensive coverage of the conda V2 plugin implementation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix ENV_DIR path to point to tests/environments
- Add tomli to test-requirements.txt
- Test results improved: 180/196 passing (92%)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add pytest-mock to test-requirements.txt for mocker fixture
- Copy 9 missing test data files from internal repo:
  - cbl_tools.txt, cbl_tools.yml
  - channel-conda.yml
  - corner-cases.txt
  - pypi-simple-no-extras.txt
  - simple.toml, toml-with-multiple-sources.toml
  - yml-with-empty-lines.yml, yml-with-unknown-section.yml

Test results improved from 186/202 (92%) to 197/202 (97.5%) passing.

Remaining 5 failures are testing internal Netflix-specific features:
- test_skip_metaflow_deps: tests --skip-metaflow-deps flag not in OSS
- test_parse_only_src_*: expects nflx-python-eureq in pinned deps
- test_environment_cli: expects named environment resolution (internal-only)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Mark 5 tests as skipped that require Netflix-internal infrastructure:
- test_parse_only_src_txt: requires nflx-python-eureq pinned dependency
- test_parse_only_src_yml: requires nflx-python-eureq pinned dependency
- test_skip_metaflow_deps: requires --skip-metaflow-deps CLI flag
- test_show_envs: requires Netflix-internal named environment
- test_resolve_all_envs: requires Netflix-internal named environment

These tests are now maintained in the internal Netflix repo where they
can run with the required infrastructure.

Test results: 197 passed, 5 skipped (was 197 passed, 5 failed)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed tests that require Netflix-internal infrastructure:
- test_environment_cli.py (5 tests): requires named environment resolution
- sample_flow.py: test flow file for environment CLI tests
- 3 tests from test_file_parsing.py:
  - test_parse_only_src_txt: expects nflx-python-eureq in pinned deps
  - test_parse_only_src_yml: expects nflx-python-eureq in pinned deps
  - test_skip_metaflow_deps: requires --skip-metaflow-deps CLI flag

These tests are now maintained in the internal Netflix repo at:
  test/plugins/conda/

OSS test results: 191 passing (was 197 passing, 5 skipped)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This parameter was missing from the OSS version but present in the internal version,
causing test_show_envs to fail when migrating to the OSS package.
The coverage plugin lives in metaflow_extensions.nflx, not netflix_ext.
Using netflix_ext caused ModuleNotFoundError in CI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
setup_coverage, coveragerc, upload_coverage_files, generate_coveragerc
have no internal Netflix deps and belong in the OSS package.
coverage_utils stays internal (uses metatron, COVERAGE_JENKINS_API_URL).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…able

OSS coveragerc has only generic settings. Netflix-specific paths stay in
the nflx package and are picked up automatically when installed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…y nflx

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ride

- Fix runtime nflx namespace reference in conda_environment.py
- Fix TYPE_CHECKING nflx refs in resolvers, utils, pypi_package_builder
- Replace COVERAGE_RCFILE constant with get_coverage_rcfile() function
  that checks METAFLOW_COVERAGE_RCFILE_PATH env var at call time

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The envsresolver.py calls resolver.resolve() with full_id_unique_keys as
the 11th argument, but CondaLockResolver, MicromambaServerResolver,
PylockTomlResolver, BuilderEnvsResolver, and the base Resolver class were
missing this parameter, causing TypeError in CI.

Also bump version to 1.3.4.dev6.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… full_id_unique_keys

Changes missing from OSS vs internal (master):
- utils.py: restore 'setuptools<82' pin in _BUILDER_ENVS_PACKAGES (pkg_resources
  removed in setuptools 82; many packages still use it in setup.py)
- pip_resolver.py: add PIP_CONSTRAINT=setuptools<82 to propagate constraint to
  pip's build isolation subprocesses (prevents pkg_resources removal there)
- pypi_package_builder.py: add PIP_CONSTRAINT=setuptools<82 for wheel building
- pylock_toml_resolver.py: propagate full_id_unique_keys through
  _translate_pylock_toml_to_resolved_env and _packages_to_resolved_env

Also bump version to 1.3.4.dev7.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n conflict

- cbl_tools.txt/yml: replace cbl_tools (Netflix-internal, not on public PyPI)
  with requests (publicly available) so test_env_create.py can resolve envs
- yml-with-empty-lines.yml: remove python=3.10 pin; test_env_create.py passes
  -p 3.8.* explicitly, so the file must not also specify python
- test_file_parsing.py: use DEFAULT_DATASTORE instead of hardcoded 's3' for
  get_pinned_conda_libs; GHA sets DEFAULT_DATASTORE=local (no S3 configured)
@npow npow added the testable PR is ready for internal Netflix testing label Mar 11, 2026
@metaflow-oss-trigger metaflow-oss-trigger Bot added testable PR is ready for internal Netflix testing and removed testable PR is ready for internal Netflix testing labels Mar 12, 2026
Nissan Pow added 2 commits March 19, 2026 16:17
…test names

- Fix METAFLOW_HACK_CONDA_CHANNEL_ALIAS → METAFLOW_CONDA_HACK_CHANNEL_ALIAS in
  test.yml so channel_or_url() correctly shortens prefix.dev URLs to 'conda-forge'
- Add pytest-mock to dev-env.yml (mocker fixture was unavailable)
- Fix expected PyPI source in test_file_parsing.py: use
  CONDA_DEFAULT_PYPI_SOURCE or 'https://pypi.org/simple' since the code
  always returns the actual pip index URL, never None
- Rename duplicate test functions in pylock_toml_resolver_test.py and remove
  duplicate deps fixture to fix pytest collection errors
Keep ray-default in get_pinned_conda_libs (ray-default is the correct
conda-forge package name; ray is the pip name, handled by
conda_deps_to_pypi_deps). 0.2.1.dev0 incorrectly used 'ray' which
is not available in conda channels.
Nissan Pow and others added 10 commits March 23, 2026 12:49
…n pin

- conda_environment.py: fix dict[EnvType, bool](...) to Dict[EnvType, bool] = {...}
  (dict[] subscript is Python 3.9+; Dict from typing works on 3.8)
- pylock_toml_resolver_test.py: add missing python_version_requested="3.10.1"
  to test_pylock_toml_to_resolved_env (required positional arg was dropped when
  duplicate test definition was removed in previous commit)
- yml-with-unknown-section.yml: remove python=3.10 pin to avoid test ID conflict
  with the python_version parametrize in test_resolve_and_check_env
- test_env_create.py: add ignore_errors=True to shutil.rmtree cleanup calls
  to prevent FileNotFoundError masking the real test failure
@npow npow marked this pull request as ready for review April 2, 2026 21:35
Nissan Pow and others added 9 commits April 2, 2026 15:13
- Coverage Report: fix --cov=metaflow_functions (no such module) to point at
  the actual source directory metaflow-functions/metaflow_extensions
- test_handle_req_txt_scenario: skip on Python <3.9 since the fixture
  requirements.txt (numpy==1.26.4) requires Python >=3.9
- channel_from_url/channel_or_url: normalize CONDA_HACK_CHANNEL_ALIAS URLs
  (e.g. prefix.dev) back to short channel names, matching existing
  conda.anaconda.org handling; fixes test_file_parsing.py failures with
  conda 26.x and mamba 1.5.10 which return expanded subdirectory URLs
- test_resolve_environment_no_crash: remove channel-conda.yml from the
  parametrize list since the comet_ml channel is only on conda.anaconda.org,
  not on the prefix.dev channel alias used in CI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…conda channels

The previous logic filtered out channels that matched defaults by computing
a set difference after channel_or_url normalization. After normalizing prefix.dev
URLs to conda.anaconda.org short names, user channels and default channels both
resolved to 'conda-forge', making the difference empty and suppressing explicit
-c flags to micromamba. This broke env resolution when Python 3.8 was requested
on macOS (py3.8 not available via prefix.dev alias).

The filtering of default channels was an accidental artifact of broken URL
normalization, not intentional. Now we always pass explicit -c flags for all
user-specified conda channels.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous fix passed ALL user channels as explicit -c flags to
micromamba, including conda-forge which is already configured in
condarc. Passing default channels explicitly confuses newer micromamba
versions (latest vs 1.5.10), causing "unsupported request" solver
errors on macOS arm64 with Python 3.8.

Now only non-default channels (those not already in default_conda_channels
after normalization) are passed as explicit -c flags. This correctly
handles both cases:
- Default-only channels (e.g. conda-forge): no explicit -c flags needed
- Extra channels (e.g. pytorch, nvidia): explicit -c flags added

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ibmamba)

Newer versions of libmamba/micromamba reject 'python==3.8' as an
"unsupported request" on osx-arm64. These tests infer the Python version
from the CI runner (no explicit version in sample_flow.py), so they fail
on any macOS + Python 3.8 CI job using a recent micromamba binary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The --cov=metaflow_functions target was wrong for this job — the extensions
tests exercise metaflow_extensions, not metaflow_functions (which isn't
even installed in this job). All .coverage files were empty, causing
coverage combine to report 'No data to report'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… runners

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Maps macOS and Linux runner absolute paths to the local checkout so
coverage combine correctly resolves sources across platforms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The file is written by setup.py at install time so it exists on test
runners but not on the coverage report runner. Path remapping can't
resolve it (requires the file to exist locally), causing `coverage xml`
to fail with "No source for code".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@npow

npow commented Apr 11, 2026

Copy link
Copy Markdown
Collaborator Author

@greptile

@npow npow merged commit bc929e0 into main Apr 14, 2026
118 of 119 checks passed
npow added a commit that referenced this pull request Jun 12, 2026
* Port missing internal PRs #1749, #1785, #1886, #1915 to OSS

These changes were merged to corp/mli-metaflow-custom but never ported to
metaflow-nflx-extensions before the migration PR (#66) removed the internal
copies. rcledat flagged this as breaking eval work.

Changes by PR:

**PR #1749 — pylock_toml_resolver sdist/vcs/archive support**
- pylock_toml_resolver.py: Support for sdist, vcs, directory, and archive
  package types (previously only wheels were supported). Adds debug logging
  throughout, marker filtering after building, and clobber guards.
- parsers.py: Strip inline comments in requirements.txt (avoids stripping
  URL fragments). Demote `--index-url` from hard error to warning+continue.
- conda_flow_mutator.py: Add `--index-strategy unsafe-best-match` to uv pip
  compile so all indices are treated equally.

**PR #1886 — Fix VCS commit field name to match PEP 751**
- pylock_toml_resolver.py: Use `commit-id` field (not `commit`) per PEP 751.
  Also support `vcs.path` for local VCS packages.

**PR #1785 — Drop support for Python < 3.10**
- utils.py: Simplify uv dep (remove python_version marker). Remove 3.7/3.8/3.9
  version maps.
- pypi_package_builder.py: Convert PackageToBuild to proper @DataClass.
- conda_lock_resolver.py: Remove the uv version selection logic gated on
  minimum Python version; just append "uv" unconditionally. Remove unused
  `re` import and `get_requirement` import.
- conda_flow_decorator.py, conda_step_decorator.py: Update docstring examples
  from Python 3.7.4 to 3.10.4.

**PR #1915 — Remote Wheel Archive**
- pylock_toml_resolver.py: When an archive entry has a remote .whl URL, use
  it directly as a wheel instead of going through the build pipeline.

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* Address review comments from codexbot

- Add comment that filter_packages_by_markers preserves object identity,
  making id()-based dedup safe
- Fix directory package cache key when version is empty (PEP 751 allows
  omitting version for local deps) — use "0" as fallback so cache key
  is well-formed
- Fix debug summary: remote archive label was "need build" even for .whl
  URLs that are used directly (PR #1915 fast-path). Changed to "may need
  build" with an inline note explaining the distinction.
- Expand --index-strategy unsafe-best-match comment to explain WHY: default
  "first-index" stops at the first index with any version of a package,
  while unsafe-best-match checks all indices for the best match — needed
  when a private index provides a newer/custom build alongside PyPI.

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: npow <npow@netflix.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testable PR is ready for internal Netflix testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants