Repository: scoutapp/scout_apm_python

Issue:
AttributeError: 'NPlusOneCallSet' object has no attribute 'should_capture_bracktrace'
When trying to upgrade to 1.1.8, I ran into this exception:

```
   File "celery/app/trace.py", line 374, in trace_task
    R = retval = fun(*args, **kwargs)
  File "myapp/celery/worker.py", line 49, in __call__
    return super().__call__(*args, **kwargs)
  File "celery/app/trace.py", line 629, in __protected_call__
    return self.run(*args, **kwargs)
  File "myapp/celery/tasks.py", line 129, in sync_backend_wagers
    retry = sync.race_wagers_sync(race_id, backend)
  File "myapp/libs/sync.py", line 52, in race_wagers_sync
    race = ents.Race.query.get(race_id)
  File "sqlalchemy/orm/query.py", line 871, in get
    ident, loading.load_on_ident)
  File "sqlalchemy/orm/query.py", line 905, in _get_impl
    return fallback_fn(self, key)
  File "sqlalchemy/orm/loading.py", line 231, in load_on_ident
    return q.one()
  File "sqlalchemy/orm/query.py", line 2837, in one
    ret = self.one_or_none()
  File "sqlalchemy/orm/query.py", line 2807, in one_or_none
    ret = list(self)
  File "sqlalchemy/orm/query.py", line 2878, in __iter__
    return self._execute_and_instances(context)
  File "sqlalchemy/orm/query.py", line 2901, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "sqlalchemy/engine/base.py", line 948, in execute
    return meth(self, multiparams, params)
  File "sqlalchemy/sql/elements.py", line 269, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "sqlalchemy/engine/base.py", line 1060, in _execute_clauseelement
    compiled_sql, distilled_params
  File "sqlalchemy/engine/base.py", line 1207, in _execute_context
    context.executemany)
  File "sqlalchemy/event/attr.py", line 256, in __call__
    fn(*args, **kw)
  File "scout_apm/sqlalchemy/__init__.py", line 16, in after_cursor_execute
    if tr.callset.should_capture_bracktrace(statement) is True:
  AttributeError: 'NPlusOneCallSet' object has no attribute 'should_capture_bracktrace'
```


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@
 from setuptools import find_packages, setup
 
 setup(name='scout_apm',
-      version='1.1.8',
+      version='1.1.9',
       description='Scout Application Performance Monitoring Agent',
       long_description='Scout Application Performance Monitoring Agent',
       url='https://github.com/scoutapp/scout_apm_python',
@@ -12,7 +12,7 @@
       author_email='support@scoutapp.com',
       license='MIT',
       zip_safe=False,
-      python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4',
+      python_requires='>=3.4, <4',
       packages=find_packages('src'),
       package_dir={'': 'src'},
       py_modules=[splitext(basename(path))[0] for path in glob('src/*.py')],
@@ -31,8 +31,6 @@
         'Operating System :: MacOS',
         'Operating System :: POSIX',
         'Operating System :: POSIX :: Linux',
-        'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
         'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
diff --git a/src/scout_apm/core/tracked_request.py b/src/scout_apm/core/tracked_request.py
--- a/src/scout_apm/core/tracked_request.py
+++ b/src/scout_apm/core/tracked_request.py
@@ -39,7 +39,7 @@ def is_real_request(self):
 
     def tag(self, key, value):
         if key in self.tags:
-            logger.debug('Overwriting previously set tag for request %s: %s' % self.req_id, key)
+            logger.debug('Overwriting previously set tag for request %s: %s' % (self.req_id, key))
         self.tags[key] = value
 
     def start_span(self, operation=None):
@@ -109,7 +109,7 @@ def stop(self):
 
     def tag(self, key, value):
         if key in self.tags:
-            logger.debug('Overwriting previously set tag for span %s: %s' % self.span_id, key)
+            logger.debug('Overwriting previously set tag for span %s: %s' % (self.span_id, key))
         self.tags[key] = value
 
     # In seconds
diff --git a/src/scout_apm/sqlalchemy/__init__.py b/src/scout_apm/sqlalchemy/__init__.py
--- a/src/scout_apm/sqlalchemy/__init__.py
+++ b/src/scout_apm/sqlalchemy/__init__.py
@@ -13,7 +13,7 @@ def after_cursor_execute(conn, cursor, statement, parameters, context, executema
         span = tr.current_span()
         if span is not None:
             tr.callset.update(statement, 1, span.duration())
-            if tr.callset.should_capture_bracktrace(statement) is True:
+            if tr.callset.should_capture_backtrace(statement) is True:
                 span.capture_backtrace()
         tr.stop_span()
 


Test patch: