From f8a12849c5af84f9af69858c01914480efd8ce03 Mon Sep 17 00:00:00 2001 From: SB-PawanN Date: Thu, 19 Mar 2026 12:01:15 +0530 Subject: [PATCH 1/3] Add __version__ attribute using VERSION file as single source of truth This implements the requested feature to expose bugsnag.__version__ for programmatic version checking, as per PEP 396. Changes: - Created VERSION file containing current version (4.8.0) - Updated bugsnag/__init__.py to read from VERSION and expose __version__ - Updated setup.py to read version from VERSION file - Updated bugsnag/notifier.py to read version from VERSION file - Added MANIFEST.in to include VERSION in package distributions - Updated CHANGELOG.md with enhancement entry - Updated CONTRIBUTING.md to document simplified release process Benefits: - Single source of truth for version number (no more manual updates in 3 places) - bugsnag.__version__ now available for programmatic access - Graceful fallback to 'unknown' if VERSION file is missing --- CHANGELOG.md | 8 ++++++++ CONTRIBUTING.md | 16 ++++++++++++++-- MANIFEST.in | 7 +++++++ VERSION | 1 + bugsnag/__init__.py | 12 +++++++++++- bugsnag/notifier.py | 12 +++++++++++- features/support/env.rb | 2 +- setup.py | 11 ++++++++--- 8 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 MANIFEST.in create mode 100644 VERSION diff --git a/CHANGELOG.md b/CHANGELOG.md index 330bdc27..1131873b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ Changelog ========= +## TBD + +### Enhancements + +* Add `__version__` attribute for programmatic version checking + * Implemented VERSION file as single source of truth for version number + * `bugsnag.__version__` now returns the installed package version + ## v4.8.0 (2024-07-08) ### Enhancements diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 901910d6..a25c6e25 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -97,9 +97,21 @@ If you're on the core team, you can release Bugsnag as follows: git checkout -b release/v4.x.x ``` -* Update the version number in [`setup.py`](./setup.py) and `bugsnag/notifier.py`(./bugsnag/notifier.py) -* Update the CHANGELOG.md and README.md if necessary +* Update the version number in the [`VERSION`](./VERSION) file + + ``` + echo "4.x.x" > VERSION + ``` + +* Update the CHANGELOG.md (add version and date) and README.md if necessary * Commit and open a pull request into `master` + + ``` + git add VERSION CHANGELOG.md + git commit -m "Release v4.x.x" + git push origin release/v4.x.x + ``` + * Merge the PR when it's been reviewed * Create a release on GitHub, tagging the new version `v4.x.x` * Push the release to PyPI diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 00000000..b01a7ad2 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,7 @@ +include VERSION +include README.md +include LICENSE.txt +include CHANGELOG.md +include UPGRADING.md +include CONTRIBUTING.md +include SECURITY.md diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..88f18119 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +4.8.0 diff --git a/bugsnag/__init__.py b/bugsnag/__init__.py index 9c023b2f..a5767916 100644 --- a/bugsnag/__init__.py +++ b/bugsnag/__init__.py @@ -1,3 +1,5 @@ +import os + from bugsnag.configuration import Configuration, RequestConfiguration from bugsnag.notification import Notification from bugsnag.event import Event @@ -18,6 +20,14 @@ clear_feature_flag, clear_feature_flags, aws_lambda_handler) +# Read version from VERSION file +_version_file = os.path.join(os.path.dirname(__file__), '..', 'VERSION') +try: + with open(_version_file, 'r') as f: + __version__ = f.read().strip() +except Exception: + __version__ = 'unknown' + __all__ = ('Client', 'Event', 'Configuration', 'RequestConfiguration', 'configuration', 'configure', 'configure_request', 'add_metadata_tab', 'clear_request_config', 'notify', @@ -27,4 +37,4 @@ 'OnBreadcrumbCallback', 'leave_breadcrumb', 'add_on_breadcrumb', 'remove_on_breadcrumb', 'FeatureFlag', 'add_feature_flag', 'add_feature_flags', 'clear_feature_flag', 'clear_feature_flags', - 'aws_lambda_handler') + 'aws_lambda_handler', '__version__') diff --git a/bugsnag/notifier.py b/bugsnag/notifier.py index c9b3b212..b75e870e 100644 --- a/bugsnag/notifier.py +++ b/bugsnag/notifier.py @@ -1,5 +1,15 @@ +import os + +# Read version from VERSION file +_version_file = os.path.join(os.path.dirname(__file__), '..', 'VERSION') +try: + with open(_version_file, 'r') as f: + _version = f.read().strip() +except Exception: + _version = 'unknown' + _NOTIFIER_INFORMATION = { 'name': 'Python Bugsnag Notifier', 'url': 'https://github.com/bugsnag/bugsnag-python', - 'version': '4.8.0' + 'version': _version } diff --git a/features/support/env.rb b/features/support/env.rb index 9f3ae675..7d7c25f8 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -36,7 +36,7 @@ def current_ip FileUtils.mkdir(destination) unless File.exist?(destination) FileUtils.cp_r( - ["bugsnag", "setup.py"], + ["bugsnag", "setup.py", "VERSION"], destination, remove_destination: true # delete destination before copying ) diff --git a/setup.py b/setup.py index 7c0b5e2e..4c6a4030 100755 --- a/setup.py +++ b/setup.py @@ -10,11 +10,16 @@ and solve your bugs as fast as possible. """ +import os from setuptools import setup, find_packages +# Read version from VERSION file +with open(os.path.join(os.path.dirname(__file__), 'VERSION'), 'r') as f: + version = f.read().strip() + setup( name='bugsnag', - version='4.8.0', + version=version, description='Automatic error monitoring for django, flask, etc.', long_description=__doc__, author='Simon Maynard', @@ -48,6 +53,6 @@ test_suite='tests', install_requires=['webob'], extras_require={ - 'flask': ['flask', 'blinker'] - }, + 'flask': [] + } ) From 866d1eca912903b5b8b7cefc866b2c7a45cd50b3 Mon Sep 17 00:00:00 2001 From: SB-PawanN Date: Thu, 19 Mar 2026 18:01:15 +0530 Subject: [PATCH 2/3] Add __version__ attribute with Makefile-based version management Implements bugsnag.__version__ for programmatic version checking (PEP 396). Uses Makefile approach (inspired by bugsnag-cocoa) to address performance concerns. Changes: - Added __version__ = '4.8.0' to bugsnag/__init__.py - Hardcoded version='4.8.0' in setup.py - Hardcoded 'version': '4.8.0' in bugsnag/notifier.py - Added Makefile with bump target for automated version updates - Updated CHANGELOG.md with enhancement entry - Updated CONTRIBUTING.md to document Makefile usage - Removed VERSION file and MANIFEST.in (no runtime file I/O overhead) - Updated features/support/env.rb (removed VERSION from test fixtures) Usage: - Users: bugsnag.__version__ returns '4.8.0' - Maintainers: make VERSION=x.y.z bump (updates all 3 files) Benefits: - Zero runtime overhead (no file I/O during import) - bugsnag.__version__ attribute now available - Automated version updates via single Makefile command - Addresses reviewer feedback on performance concerns --- CHANGELOG.md | 2 +- CONTRIBUTING.md | 6 +++--- MANIFEST.in | 7 ------- Makefile | 12 ++++++++++++ VERSION | 1 - bugsnag/__init__.py | 10 +--------- bugsnag/notifier.py | 12 +----------- features/support/env.rb | 2 +- setup.py | 7 +------ 9 files changed, 20 insertions(+), 39 deletions(-) delete mode 100644 MANIFEST.in create mode 100644 Makefile delete mode 100644 VERSION diff --git a/CHANGELOG.md b/CHANGELOG.md index 1131873b..b4f55edf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,8 @@ Changelog ### Enhancements * Add `__version__` attribute for programmatic version checking - * Implemented VERSION file as single source of truth for version number * `bugsnag.__version__` now returns the installed package version + * Follows PEP 396 specification ## v4.8.0 (2024-07-08) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a25c6e25..e0072bd2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -97,17 +97,17 @@ If you're on the core team, you can release Bugsnag as follows: git checkout -b release/v4.x.x ``` -* Update the version number in the [`VERSION`](./VERSION) file +* Update the version number using the Makefile ``` - echo "4.x.x" > VERSION + make VERSION=4.x.x bump ``` * Update the CHANGELOG.md (add version and date) and README.md if necessary * Commit and open a pull request into `master` ``` - git add VERSION CHANGELOG.md + git add bugsnag/__init__.py setup.py bugsnag/notifier.py CHANGELOG.md git commit -m "Release v4.x.x" git push origin release/v4.x.x ``` diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index b01a7ad2..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,7 +0,0 @@ -include VERSION -include README.md -include LICENSE.txt -include CHANGELOG.md -include UPGRADING.md -include CONTRIBUTING.md -include SECURITY.md diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..7a2e6c4b --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +.PHONY: bump + +bump: ## Bump the version numbers to $VERSION +ifeq ($(VERSION),) + @$(error VERSION is not defined. Run with `make VERSION=number bump`) +endif + @echo Bumping the version number to $(VERSION) + @sed -i.bak "s/__version__ = '.*'/__version__ = '$(VERSION)'/" bugsnag/__init__.py && rm bugsnag/__init__.py.bak + @sed -i.bak "s/version='.*',/version='$(VERSION)',/" setup.py && rm setup.py.bak + @sed -i.bak "s/'version': '.*'/'version': '$(VERSION)'/" bugsnag/notifier.py && rm bugsnag/notifier.py.bak + @echo "Successfully bumped version to $(VERSION)" + @echo "Updated files: bugsnag/__init__.py, setup.py, bugsnag/notifier.py" diff --git a/VERSION b/VERSION deleted file mode 100644 index 88f18119..00000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -4.8.0 diff --git a/bugsnag/__init__.py b/bugsnag/__init__.py index a5767916..6c4c9b6a 100644 --- a/bugsnag/__init__.py +++ b/bugsnag/__init__.py @@ -1,5 +1,3 @@ -import os - from bugsnag.configuration import Configuration, RequestConfiguration from bugsnag.notification import Notification from bugsnag.event import Event @@ -20,13 +18,7 @@ clear_feature_flag, clear_feature_flags, aws_lambda_handler) -# Read version from VERSION file -_version_file = os.path.join(os.path.dirname(__file__), '..', 'VERSION') -try: - with open(_version_file, 'r') as f: - __version__ = f.read().strip() -except Exception: - __version__ = 'unknown' +__version__ = '4.8.0' __all__ = ('Client', 'Event', 'Configuration', 'RequestConfiguration', 'configuration', 'configure', 'configure_request', diff --git a/bugsnag/notifier.py b/bugsnag/notifier.py index b75e870e..c9b3b212 100644 --- a/bugsnag/notifier.py +++ b/bugsnag/notifier.py @@ -1,15 +1,5 @@ -import os - -# Read version from VERSION file -_version_file = os.path.join(os.path.dirname(__file__), '..', 'VERSION') -try: - with open(_version_file, 'r') as f: - _version = f.read().strip() -except Exception: - _version = 'unknown' - _NOTIFIER_INFORMATION = { 'name': 'Python Bugsnag Notifier', 'url': 'https://github.com/bugsnag/bugsnag-python', - 'version': _version + 'version': '4.8.0' } diff --git a/features/support/env.rb b/features/support/env.rb index 7d7c25f8..9f3ae675 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -36,7 +36,7 @@ def current_ip FileUtils.mkdir(destination) unless File.exist?(destination) FileUtils.cp_r( - ["bugsnag", "setup.py", "VERSION"], + ["bugsnag", "setup.py"], destination, remove_destination: true # delete destination before copying ) diff --git a/setup.py b/setup.py index 4c6a4030..2475c243 100755 --- a/setup.py +++ b/setup.py @@ -10,16 +10,11 @@ and solve your bugs as fast as possible. """ -import os from setuptools import setup, find_packages -# Read version from VERSION file -with open(os.path.join(os.path.dirname(__file__), 'VERSION'), 'r') as f: - version = f.read().strip() - setup( name='bugsnag', - version=version, + version='4.8.0', description='Automatic error monitoring for django, flask, etc.', long_description=__doc__, author='Simon Maynard', From 8916729970c33664b8b13525f36f4143b08f1eab Mon Sep 17 00:00:00 2001 From: SB-PawanN Date: Thu, 19 Mar 2026 23:06:19 +0530 Subject: [PATCH 3/3] Address review feedback - Restore flask extras_require (accidental removal) - Update CHANGELOG.md format per reviewer suggestion - All 532 core unit tests passing --- CHANGELOG.md | 5 ++--- setup.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4f55edf..de9b179c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,8 @@ Changelog ### Enhancements -* Add `__version__` attribute for programmatic version checking - * `bugsnag.__version__` now returns the installed package version - * Follows PEP 396 specification +* Add `bugsnag.__version__` attribute for programmatic version checking as per PEP 396 specification + [#409](https://github.com/bugsnag/bugsnag-python/pull/409) ## v4.8.0 (2024-07-08) diff --git a/setup.py b/setup.py index 2475c243..dccb2fbb 100755 --- a/setup.py +++ b/setup.py @@ -48,6 +48,6 @@ test_suite='tests', install_requires=['webob'], extras_require={ - 'flask': [] + 'flask': ['flask', 'blinker'] } )