From 5d2f86c0f46826439c572559da5015af0b1e4263 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 Aug 2025 11:51:39 +0000 Subject: [PATCH 1/6] Initial plan From 4e4956f48e9166decfdce306578a01f2102eef89 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 Aug 2025 11:58:10 +0000 Subject: [PATCH 2/6] Parameterize Python versions in CI workflow to support latest stable + 4 previous versions Co-authored-by: xgboosted <1528712+xgboosted@users.noreply.github.com> --- .github/workflows/ci.yml | 10 ++++++++-- setup.py | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d64ab9d..8af89eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,10 @@ on: branches: [ main ] workflow_dispatch: +env: + # Latest stable Python version - update this when new Python versions are released + LATEST_PYTHON_VERSION: "3.13" + jobs: # Basic structure validation that doesn't require dependencies validate: @@ -17,7 +21,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: '3.10' + python-version: ${{ env.LATEST_PYTHON_VERSION }} - name: Validate package structure run: | @@ -28,7 +32,9 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.10', '3.11', '3.12'] + # Support latest stable Python version and 4 consecutive previous versions + # Update LATEST_PYTHON_VERSION env var when new Python versions are released + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 diff --git a/setup.py b/setup.py index dad28c7..7021d5a 100644 --- a/setup.py +++ b/setup.py @@ -32,9 +32,11 @@ license="The MIT License (MIT)", classifiers=[ "Development Status :: 4 - Beta", + "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "License :: OSI Approved :: MIT License", "Natural Language :: English", From e2b32c038207ddd45ba068aa64e3a823848e7e24 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 Aug 2025 12:30:59 +0000 Subject: [PATCH 3/6] Derive Python versions dynamically from latest version constant - Added generate-matrix job to calculate Python versions programmatically - Extracts minor version from LATEST_PYTHON_VERSION and generates 5 versions (latest + 4 previous) - Test job now depends on generate-matrix and uses fromJSON() to parse the dynamic matrix - Maintains the same 5-version support window while making it fully parameterized Co-authored-by: xgboosted <1528712+xgboosted@users.noreply.github.com> --- .github/workflows/ci.yml | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8af89eb..d6c9687 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,34 @@ env: LATEST_PYTHON_VERSION: "3.13" jobs: + # Generate Python version matrix based on latest version + generate-matrix: + runs-on: ubuntu-latest + outputs: + python-versions: ${{ steps.versions.outputs.python-versions }} + steps: + - name: Generate Python version matrix + id: versions + run: | + # Extract minor version from LATEST_PYTHON_VERSION (e.g., "3.13" -> "13") + latest="${{ env.LATEST_PYTHON_VERSION }}" + minor_version=$(echo "$latest" | cut -d'.' -f2) + + # Generate 5 versions: latest and 4 previous minor versions + versions="[" + for i in {4..0}; do + version_num=$((minor_version - i)) + if [ $i -eq 0 ]; then + versions="${versions}\"3.${version_num}\"" + else + versions="${versions}\"3.${version_num}\", " + fi + done + versions="${versions}]" + + echo "python-versions=$versions" >> $GITHUB_OUTPUT + echo "Generated Python versions: $versions" + # Basic structure validation that doesn't require dependencies validate: runs-on: ubuntu-latest @@ -29,12 +57,13 @@ jobs: # Full test suite with dependencies test: + needs: generate-matrix runs-on: ubuntu-latest strategy: matrix: - # Support latest stable Python version and 4 consecutive previous versions - # Update LATEST_PYTHON_VERSION env var when new Python versions are released - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] + # Python versions are dynamically generated from LATEST_PYTHON_VERSION + # Supports latest stable Python version and 4 consecutive previous versions + python-version: ${{ fromJSON(needs.generate-matrix.outputs.python-versions) }} steps: - uses: actions/checkout@v4 From 83f7132dc53173654589854b5090fd6fd680d528 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 Aug 2025 12:40:13 +0000 Subject: [PATCH 4/6] Synchronize setup.py Python versions with CI workflow using dynamic generation Co-authored-by: xgboosted <1528712+xgboosted@users.noreply.github.com> --- setup.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 7021d5a..0fa5bf4 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,22 @@ # -*- coding: utf-8 -*- from distutils.core import setup +# Latest stable Python version - update this when new Python versions are released +LATEST_PYTHON_VERSION = "3.13" + +def generate_python_classifiers(): + """Generate Python version classifiers based on latest version constant.""" + # Extract minor version from LATEST_PYTHON_VERSION (e.g., "3.13" -> 13) + minor_version = int(LATEST_PYTHON_VERSION.split('.')[1]) + + # Generate classifiers for latest and 4 previous minor versions + classifiers = [] + for i in range(4, -1, -1): # 4, 3, 2, 1, 0 + version_num = minor_version - i + classifiers.append(f"Programming Language :: Python :: 3.{version_num}") + + return classifiers + long_description = "An easy to use Python 3 Pandas Extension with 130+ Technical Analysis Indicators. Can be called from a Pandas DataFrame or standalone like TA-Lib. Correlation tested with TA-Lib. This is the classic/community maintained version." setup( @@ -32,11 +48,7 @@ license="The MIT License (MIT)", classifiers=[ "Development Status :: 4 - Beta", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", + ] + generate_python_classifiers() + [ "Operating System :: OS Independent", "License :: OSI Approved :: MIT License", "Natural Language :: English", From 5b4a01e7fdc00f35ea64460f3d9bc21f74b10b94 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 Aug 2025 12:52:44 +0000 Subject: [PATCH 5/6] Refactor to update setup.py dynamically via CI plaintext replacement instead of dedicated code Co-authored-by: xgboosted <1528712+xgboosted@users.noreply.github.com> --- .github/workflows/ci.yml | 42 ++++++++++++++++++++++++ setup.py | 22 +++---------- setup.py.backup | 69 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 17 deletions(-) create mode 100644 setup.py.backup diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d6c9687..c432737 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,6 +68,48 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Update setup.py with dynamic Python classifiers + run: | + python << 'EOF' + # Simple approach: read setup.py, find Python classifier lines, and replace them + latest_version = "${{ env.LATEST_PYTHON_VERSION }}" + minor_version = int(latest_version.split('.')[1]) + + # Generate the 5 versions we want + target_versions = [] + for i in range(4, -1, -1): # 4, 3, 2, 1, 0 + version_num = minor_version - i + target_versions.append(f"3.{version_num}") + + # Read setup.py + with open('setup.py', 'r') as f: + content = f.read() + + # Find and replace each Python classifier line + lines = content.split('\n') + version_index = 0 + + for i, line in enumerate(lines): + if '"Programming Language :: Python :: 3.' in line and version_index < len(target_versions): + # Replace the version number in this line + import re + new_line = re.sub(r'3\.\d+', target_versions[version_index], line) + lines[i] = new_line + version_index += 1 + + # Write back to setup.py + with open('setup.py', 'w') as f: + f.write('\n'.join(lines)) + + print(f"Updated setup.py with Python versions: {', '.join(target_versions)}") + + # Verify the changes + with open('setup.py', 'r') as f: + for line_num, line in enumerate(f, 1): + if '"Programming Language :: Python :: 3.' in line: + print(f"Line {line_num}: {line.strip()}") + EOF + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: diff --git a/setup.py b/setup.py index 0fa5bf4..12fb0e3 100644 --- a/setup.py +++ b/setup.py @@ -1,22 +1,6 @@ # -*- coding: utf-8 -*- from distutils.core import setup -# Latest stable Python version - update this when new Python versions are released -LATEST_PYTHON_VERSION = "3.13" - -def generate_python_classifiers(): - """Generate Python version classifiers based on latest version constant.""" - # Extract minor version from LATEST_PYTHON_VERSION (e.g., "3.13" -> 13) - minor_version = int(LATEST_PYTHON_VERSION.split('.')[1]) - - # Generate classifiers for latest and 4 previous minor versions - classifiers = [] - for i in range(4, -1, -1): # 4, 3, 2, 1, 0 - version_num = minor_version - i - classifiers.append(f"Programming Language :: Python :: 3.{version_num}") - - return classifiers - long_description = "An easy to use Python 3 Pandas Extension with 130+ Technical Analysis Indicators. Can be called from a Pandas DataFrame or standalone like TA-Lib. Correlation tested with TA-Lib. This is the classic/community maintained version." setup( @@ -48,7 +32,11 @@ def generate_python_classifiers(): license="The MIT License (MIT)", classifiers=[ "Development Status :: 4 - Beta", - ] + generate_python_classifiers() + [ + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "License :: OSI Approved :: MIT License", "Natural Language :: English", diff --git a/setup.py.backup b/setup.py.backup new file mode 100644 index 0000000..12fb0e3 --- /dev/null +++ b/setup.py.backup @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +from distutils.core import setup + +long_description = "An easy to use Python 3 Pandas Extension with 130+ Technical Analysis Indicators. Can be called from a Pandas DataFrame or standalone like TA-Lib. Correlation tested with TA-Lib. This is the classic/community maintained version." + +setup( + name="pandas-ta-classic", + packages=[ + "pandas_ta_classic", + "pandas_ta_classic.candles", + "pandas_ta_classic.cycles", + "pandas_ta_classic.momentum", + "pandas_ta_classic.overlap", + "pandas_ta_classic.performance", + "pandas_ta_classic.statistics", + "pandas_ta_classic.trend", + "pandas_ta_classic.utils", + "pandas_ta_classic.utils.data", + "pandas_ta_classic.volatility", + "pandas_ta_classic.volume" + ], + version=".".join(("0", "3", "14b1")), + description=long_description, + long_description=long_description, + author="xgboosted", + author_email="", + url="https://github.com/xgboosted/pandas-ta-classic", + maintainer="xgboosted", + maintainer_email="", + download_url="https://github.com/xgboosted/pandas-ta-classic.git", + keywords=["technical analysis", "trading", "python3", "pandas"], + license="The MIT License (MIT)", + classifiers=[ + "Development Status :: 4 - Beta", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Operating System :: OS Independent", + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Intended Audience :: Developers", + "Intended Audience :: Financial and Insurance Industry", + "Intended Audience :: Science/Research", + "Topic :: Office/Business :: Financial", + "Topic :: Office/Business :: Financial :: Investment", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Information Analysis", + ], + package_data={ + "data": ["data/*.csv"], + }, + install_requires=[ + "numpy>=2.0.0", + "pandas>=2.0.0" + ], + # List additional groups of dependencies here (e.g. development dependencies). + # You can install these using the following syntax, for example: + # $ pip install -e .[dev,test] + extras_require={ + "dev": [ + "alphaVantage-api", "matplotlib", "mplfinance", "scipy", + "sklearn", "statsmodels", "stochastic", + "talib", "tqdm", "vectorbt", "yfinance", + ], + "test": ["ta-lib"], + }, +) From eb3576f1b392665fdf9e4deb0a040185ff820db4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 2 Aug 2025 12:53:47 +0000 Subject: [PATCH 6/6] Add backup files pattern to .gitignore and remove accidentally committed backup Co-authored-by: xgboosted <1528712+xgboosted@users.noreply.github.com> --- .gitignore | 5 +++- setup.py.backup | 69 ------------------------------------------------- 2 files changed, 4 insertions(+), 70 deletions(-) delete mode 100644 setup.py.backup diff --git a/.gitignore b/.gitignore index bbc88c1..a08f69b 100644 --- a/.gitignore +++ b/.gitignore @@ -149,4 +149,7 @@ jnb/*.txt _site/ # Validation artifacts (temp files from our validation script) -validate_structure.py.tmp \ No newline at end of file +validate_structure.py.tmp + +# Backup files +*.backup \ No newline at end of file diff --git a/setup.py.backup b/setup.py.backup deleted file mode 100644 index 12fb0e3..0000000 --- a/setup.py.backup +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -from distutils.core import setup - -long_description = "An easy to use Python 3 Pandas Extension with 130+ Technical Analysis Indicators. Can be called from a Pandas DataFrame or standalone like TA-Lib. Correlation tested with TA-Lib. This is the classic/community maintained version." - -setup( - name="pandas-ta-classic", - packages=[ - "pandas_ta_classic", - "pandas_ta_classic.candles", - "pandas_ta_classic.cycles", - "pandas_ta_classic.momentum", - "pandas_ta_classic.overlap", - "pandas_ta_classic.performance", - "pandas_ta_classic.statistics", - "pandas_ta_classic.trend", - "pandas_ta_classic.utils", - "pandas_ta_classic.utils.data", - "pandas_ta_classic.volatility", - "pandas_ta_classic.volume" - ], - version=".".join(("0", "3", "14b1")), - description=long_description, - long_description=long_description, - author="xgboosted", - author_email="", - url="https://github.com/xgboosted/pandas-ta-classic", - maintainer="xgboosted", - maintainer_email="", - download_url="https://github.com/xgboosted/pandas-ta-classic.git", - keywords=["technical analysis", "trading", "python3", "pandas"], - license="The MIT License (MIT)", - classifiers=[ - "Development Status :: 4 - Beta", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Operating System :: OS Independent", - "License :: OSI Approved :: MIT License", - "Natural Language :: English", - "Intended Audience :: Developers", - "Intended Audience :: Financial and Insurance Industry", - "Intended Audience :: Science/Research", - "Topic :: Office/Business :: Financial", - "Topic :: Office/Business :: Financial :: Investment", - "Topic :: Scientific/Engineering", - "Topic :: Scientific/Engineering :: Information Analysis", - ], - package_data={ - "data": ["data/*.csv"], - }, - install_requires=[ - "numpy>=2.0.0", - "pandas>=2.0.0" - ], - # List additional groups of dependencies here (e.g. development dependencies). - # You can install these using the following syntax, for example: - # $ pip install -e .[dev,test] - extras_require={ - "dev": [ - "alphaVantage-api", "matplotlib", "mplfinance", "scipy", - "sklearn", "statsmodels", "stochastic", - "talib", "tqdm", "vectorbt", "yfinance", - ], - "test": ["ta-lib"], - }, -)