Skip to content

Conversation

@trispera
Copy link
Member

@trispera trispera commented Jan 30, 2026

  • Update to alpine:3.22 (python 3.12)
  • Update tox
  • Update setup.py
  • Fix pylint

https://endoflife.date/python

Summary by Sourcery

Update supported Python versions, dependencies, and container images while addressing linting issues and path handling.

Bug Fixes:

  • Fix directory creation when downloading FTP files to avoid using deprecated distutils utilities.
  • Correct regex escaping in S3 filer path handling.
  • Fix test assertion usage to comply with current unittest APIs.

Enhancements:

  • Drop support for older Python versions and configure tox and GitHub Actions to test only on Python 3.11 and 3.12.
  • Refresh package dependencies, including kubernetes, urllib3, and boto3 constraints, and clean up legacy setup.py metadata.
  • Modernize Docker build process by upgrading filer and taskmaster images to Alpine 3.23 and using python -m build for wheel creation.
  • Fix configuration typos in setup.cfg metadata key for README description.

- Update to alpine:3.22 (python 3.12)
- Update tox
- Update setup.py
- Fix pylint
@sourcery-ai
Copy link

sourcery-ai bot commented Jan 30, 2026

Reviewer's Guide

Modernizes Python/runtime support to 3.11–3.12, updates dependencies and Docker build flow to use alpine:3.23 and PEP 517 builds, and fixes minor linting/test issues in filer-related code.

Flow diagram for updated multi-stage Docker build for filer and taskmaster

flowchart TD
    A[Start multi-stage Docker build] --> B[Builder stage based on alpine:3.23]
    B --> C[Install python3 and py3-pip]
    C --> D[Install git]
    D --> E[Upgrade setuptools, pip, wheel, build]
    E --> F[Set WORKDIR /app and copy source]
    F --> G[Run python3 -m build --wheel]
    G --> H[Remove sdist files from dist]
    H --> I[Runtime stage based on alpine:3.23]
    I --> J[Install python3 and py3-pip]
    J --> K[Copy built wheel from builder]
    K --> L[Install tesk_core wheel with dependencies]
    L --> M[Image ready for filer or taskmaster]
Loading

File-Level Changes

Change Details Files
Narrow supported/CI-tested Python versions to 3.11 and 3.12 and update tox configuration accordingly.
  • Adjust tox envlist to only define py311/py312 unit and lint environments
  • Update dependency factor settings in tox deps for py311/py312 groups
  • Align commands section to run pytest/coverage and pylint only for py311/py312 factors
  • Update GitHub Actions tox workflow matrix to only run for Python 3.11 and 3.12
tox.ini
.github/workflows/tox.yml
Refresh packaging configuration and dependency pins for newer Kubernetes, urllib3, and boto3 and simplify legacy test-related setup arguments.
  • Bump kubernetes requirement from 9.0.0 to 35.0.0
  • Consolidate urllib3 constraints into a single python>=3.10 marker with <3.0 upper bound
  • Drop legacy boto3 pin for Python 3.8 and keep a single constraint for Python>=3.9
  • Remove obsolete setup.py arguments like Apache license classifier, test_suite, and tests_require while keeping core metadata
  • Fix setup.cfg metadata key from description-file to description_file
setup.py
setup.cfg
Update filer and taskmaster container images to alpine:3.23 and switch wheel building to use python -m build.
  • Bump base and builder images from alpine:3.19 to alpine:3.23 for both filer and taskmaster Dockerfiles
  • Install the build package alongside setuptools/pip/wheel in the builder stage
  • Replace python3 setup.py bdist_wheel with python3 -m build --wheel and clean up source tarballs in dist
containers/filer.Dockerfile
containers/taskmaster.Dockerfile
Fix linting and path handling issues in filer code for FTP and S3 operations and modernize a test assertion.
  • Use a raw-string regex in filer.copyFile to avoid escape warnings
  • Replace distutils.dir_util.mkpath with an os.makedirs call guarded by an existence check when preparing FTP download directories
  • Use a raw-string escape in the S3 regex replacement when building subdirectory paths
  • Update a deprecated unittest assertion from assertEquals to assertEqual
src/tesk_core/filer.py
src/tesk_core/filer_s3.py
tests/test_filer.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 4 issues, and left some high level feedback:

  • The supported Python versions are now effectively 3.11–3.12 in tox and CI, but python_requires and the classifiers in setup.py still claim support down to 3.5/3.7; consider tightening python_requires and updating classifiers to match the actually tested versions.
  • The new urllib3 requirement only applies for python_version >= "3.10" and nothing is specified for lower versions while python_requires still allows them; either add constraints for pre-3.10 or drop support for those versions so dependency resolution remains consistent.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The supported Python versions are now effectively 3.11–3.12 in tox and CI, but `python_requires` and the classifiers in `setup.py` still claim support down to 3.5/3.7; consider tightening `python_requires` and updating classifiers to match the actually tested versions.
- The new `urllib3` requirement only applies for `python_version >= "3.10"` and nothing is specified for lower versions while `python_requires` still allows them; either add constraints for pre-3.10 or drop support for those versions so dependency resolution remains consistent.

## Individual Comments

### Comment 1
<location> `setup.py:11` </location>
<code_context>
 with codecs.open(path.join(HERE, 'README.md'), encoding='utf-8') as f:
     LONG_DESC = f.read()

-INSTALL_DEPS = ['kubernetes==9.0.0',
+INSTALL_DEPS = ['kubernetes==35.0.0',
                 'requests>=2.20.0',

</code_context>

<issue_to_address>
**issue (bug_risk):** Upgrading kubernetes dependency may require aligning supported Python versions with upstream requirements.

This is a large jump (`kubernetes==9.0.0``35.0.0`), and newer kubernetes client versions have dropped support for some older Python versions. Since `python_requires` still allows `>=3.5`, users on unsupported Python versions could hit install-time or runtime failures. Please either update `python_requires` to match the kubernetes client's supported versions or conditionally pin kubernetes by Python version.
</issue_to_address>

### Comment 2
<location> `setup.py:19-16` </location>
<code_context>
+                'urllib3>=2.6.0,<3.0 ; python_version >= "3.10"',

-                # boto3 constraint
-                'boto3<=1.28 ; python_version == "3.8"',
                 'boto3>=1.28,<2.0 ; python_version >= "3.9"',
                 ]
 TEST_DEPS = [ 'pytest',
</code_context>

<issue_to_address>
**issue (bug_risk):** boto3 constraint no longer mentions Python 3.8, while `python_requires` still allows it.

With `python_requires` still set to `>=3.5,<4.0`, a Python 3.8 environment can install this project but won’t match the new `boto3>=1.28,<2.0 ; python_version >= "3.9"` specifier, leaving boto3 effectively unconstrained. If 3.8 is no longer supported, please update `python_requires` (and classifiers) accordingly; if it is supported, consider reintroducing a 3.8-specific boto3 constraint or broadening the current one so 3.8 is covered explicitly.
</issue_to_address>

### Comment 3
<location> `setup.py:56` </location>
<code_context>

-        'License :: OSI Approved :: Apache Software License',
-
         'Programming Language :: Python :: 3',
         'Programming Language :: Python :: 3.7'
     ],
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Classifier list and `python_requires` are out of sync with the new tox/GitHub Actions matrices.

Tox and the GitHub workflow only exercise Python 3.11 and 3.12, but the metadata still claims support for 3.7 and `python_requires='>=3.5, <4.0'`. This can mislead users and cause installs on unsupported versions, especially given the newer kubernetes/boto3/urllib3 constraints. Please align `python_requires` and classifiers with the versions you actually support (e.g., >=3.11, or the true minimum compatible version).
</issue_to_address>

### Comment 4
<location> `src/tesk_core/filer_s3.py:103` </location>
<code_context>
         for obj in objects["Contents"]:
             file_name = os.path.basename(obj["Key"])
             dir_name = os.path.dirname(obj["Key"])
-            path_to_create = re.sub(r'^' + self.file_path.strip('/').replace('/', '\/') + '', "", dir_name).strip('/')
+            path_to_create = re.sub(r'^' + self.file_path.strip('/').replace('/', r'\/') + '', "", dir_name).strip('/')
             path_to_create = os.path.join(self.path, path_to_create)
             os.makedirs(path_to_create, exist_ok=True)
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Building the regex prefix by hand is fragile; `re.escape` would avoid issues with special characters.

This still manually builds a regex with `self.file_path.strip('/').replace('/', r'\/')`. If `self.file_path` contains other regex metacharacters (like `.` or `+`), the match can behave incorrectly. Please use `re.escape` for the dynamic prefix instead:

```python
prefix = re.escape(self.file_path.strip('/'))
path_to_create = re.sub(r'^' + prefix, '', dir_name).strip('/')
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

for obj in objects["Contents"]:
file_name = os.path.basename(obj["Key"])
dir_name = os.path.dirname(obj["Key"])
path_to_create = re.sub(r'^' + self.file_path.strip('/').replace('/', '\/') + '', "", dir_name).strip('/')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Building the regex prefix by hand is fragile; re.escape would avoid issues with special characters.

This still manually builds a regex with self.file_path.strip('/').replace('/', r'\/'). If self.file_path contains other regex metacharacters (like . or +), the match can behave incorrectly. Please use re.escape for the dynamic prefix instead:

prefix = re.escape(self.file_path.strip('/'))
path_to_create = re.sub(r'^' + prefix, '', dir_name).strip('/')

@trispera trispera changed the title Update filer and taskmaster WIP: Update filer and taskmaster Jan 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants