coveralls: 
[![Coverage Status](https://coveralls.io/builds/18793148/badge)](https://coveralls.io/builds/18793148)

Coverage increased (+0.001%) to 98.92% when pulling **85dd0013e90f63127e2afd18cc4f3631b3c03a1a on gruppe-adler:scopefix** into **a9a1de31e439742cc5391c6ca7e4cd7f2c2bdf15 on LordGolias:master**.

LordGolias: Thanks a lot for this PR. 

I like the idea. I think that we can do better than this though: when spawn is called, `_this` has the type passed by its argument. Therefore, we know the type of `_this`.

For example, 

```
"foo" spawn {sleep _this}
```
should return a type error as `_this` is of type String instead of Number.

What do you think? Do you see any reason to not have this altogether?
Fusselwurm: @LordGolias works, I guess :)
diff --git a/sqf/analyzer.py b/sqf/analyzer.py
index 1c55885..b4ceea7 100644
--- a/sqf/analyzer.py
+++ b/sqf/analyzer.py
@@ -426,7 +426,7 @@ class Analyzer(BaseInterpreter):
             elif case_found.keyword == Keyword('catch'):
                 extra_scope = {'_exception': Anything()}
             elif case_found.keyword == Keyword('spawn'):
-                extra_scope = {'_thisScript': Script()}
+                extra_scope = {'_thisScript': Script(), '_this': values[0]}
             elif case_found.keyword == Keyword('do') and type(values[0]) == ForType:
                 extra_scope = {values[0].variable.value: Number()}
             for value, t_or_v in zip(values, case_found.types_or_values):

scope warning when using _this in spawned code block
`[2,13]:warning:Local variable "_this" is not from this scope (not private)` when running sqflint over

```sqf
_this spawn {
    hint str _this;
};
```
it does *not* complain when the code block is *call*ed, though.

diff --git a/tests/test_analyzer.py b/tests/test_analyzer.py
index b12b769..91bc548 100644
--- a/tests/test_analyzer.py
+++ b/tests/test_analyzer.py
@@ -1052,11 +1052,21 @@ class SpecialContext(TestCase):
         analyzer = analyze(parse(code))
         self.assertEqual(analyzer.exceptions, [])
 
-    def test_spawn(self):
+    def test_spawn_thisScript(self):
         code = '[] spawn {x = _thisScript}'
         analyzer = analyze(parse(code))
         self.assertEqual(len(analyzer.exceptions), 0)
 
+    def test_spawn_this_typing_correct(self):
+        code = '"" spawn {hint _this}'
+        analyzer = analyze(parse(code))
+        self.assertEqual(len(analyzer.exceptions), 0)
+
+    def test_spawn_this_typing_error(self):
+        code = '[] spawn {hint _this}'
+        analyzer = analyze(parse(code))
+        self.assertEqual(len(analyzer.exceptions), 1)
+
     def test_spawn_local_vars(self):
         # spawn should not use local variables because they may become undefined (error 1). Likewise,
         # the local variable becomes unused (error 2).

pip install -e .
parse_log_pytest
pytest
pytest
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
packaging @ file:///croot/packaging_1734472117206/work
pluggy @ file:///croot/pluggy_1733169602837/work
pytest @ file:///croot/pytest_1738938843180/work
-e git+https://github.com/LordGolias/sqf.git@a9a1de31e439742cc5391c6ca7e4cd7f2c2bdf15#egg=sqflint
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work

name: sqf
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py39h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.2=py39h06a4308_0
  - pip=25.0=py39h06a4308_0
  - pluggy=1.5.0=py39h06a4308_0
  - pytest=8.3.4=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py39h06a4308_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
prefix: /opt/conda/envs/sqf

tests/test_analyzer.py::SpecialContext::test_spawn_this_typing_correct
tests/test_analyzer.py::GeneralTestCase::test__this tests/test_analyzer.py::GeneralTestCase::test_assign_wrong tests/test_analyzer.py::GeneralTestCase::test_call tests/test_analyzer.py::GeneralTestCase::test_call_recursive tests/test_analyzer.py::GeneralTestCase::test_change_types tests/test_analyzer.py::GeneralTestCase::test_count_with_config_and_minus tests/test_analyzer.py::GeneralTestCase::test_custom_function tests/test_analyzer.py::GeneralTestCase::test_error_bla tests/test_analyzer.py::GeneralTestCase::test_error_double tests/test_analyzer.py::GeneralTestCase::test_error_in tests/test_analyzer.py::GeneralTestCase::test_error_message_binary tests/test_analyzer.py::GeneralTestCase::test_error_message_unary tests/test_analyzer.py::GeneralTestCase::test_evaluate tests/test_analyzer.py::GeneralTestCase::test_for_code tests/test_analyzer.py::GeneralTestCase::test_for_missing_do tests/test_analyzer.py::GeneralTestCase::test_for_specs tests/test_analyzer.py::GeneralTestCase::test_foreach tests/test_analyzer.py::GeneralTestCase::test_foreach_error tests/test_analyzer.py::GeneralTestCase::test_foreach_no_error tests/test_analyzer.py::GeneralTestCase::test_foreach_no_errors tests/test_analyzer.py::GeneralTestCase::test_foreach_variable tests/test_analyzer.py::GeneralTestCase::test_getConfig tests/test_analyzer.py::GeneralTestCase::test_get_variable_unknown_first_element tests/test_analyzer.py::GeneralTestCase::test_getset_variable_undefined tests/test_analyzer.py::GeneralTestCase::test_global tests/test_analyzer.py::GeneralTestCase::test_if tests/test_analyzer.py::GeneralTestCase::test_if_missing_then tests/test_analyzer.py::GeneralTestCase::test_if_then tests/test_analyzer.py::GeneralTestCase::test_if_then_else tests/test_analyzer.py::GeneralTestCase::test_if_then_specs tests/test_analyzer.py::GeneralTestCase::test_insensitive_variables tests/test_analyzer.py::GeneralTestCase::test_logical_with_nothing tests/test_analyzer.py::GeneralTestCase::test_lowercase tests/test_analyzer.py::GeneralTestCase::test_missing_op tests/test_analyzer.py::GeneralTestCase::test_missing_semi_colon tests/test_analyzer.py::GeneralTestCase::test_missing_while_bracket tests/test_analyzer.py::GeneralTestCase::test_multiple_returns_is_nothing tests/test_analyzer.py::GeneralTestCase::test_negation_priority tests/test_analyzer.py::GeneralTestCase::test_precedence_fail tests/test_analyzer.py::GeneralTestCase::test_precedence_nullary tests/test_analyzer.py::GeneralTestCase::test_precedence_various tests/test_analyzer.py::GeneralTestCase::test_priority tests/test_analyzer.py::GeneralTestCase::test_private_empty tests/test_analyzer.py::GeneralTestCase::test_private_eq1 tests/test_analyzer.py::GeneralTestCase::test_private_global tests/test_analyzer.py::GeneralTestCase::test_private_many tests/test_analyzer.py::GeneralTestCase::test_private_no_errors tests/test_analyzer.py::GeneralTestCase::test_private_single tests/test_analyzer.py::GeneralTestCase::test_private_var_error tests/test_analyzer.py::GeneralTestCase::test_private_wrong tests/test_analyzer.py::GeneralTestCase::test_private_wrong_exp tests/test_analyzer.py::GeneralTestCase::test_recursive_assign tests/test_analyzer.py::GeneralTestCase::test_set_and_get_together tests/test_analyzer.py::GeneralTestCase::test_statement tests/test_analyzer.py::GeneralTestCase::test_throw tests/test_analyzer.py::GeneralTestCase::test_undefined_sum tests/test_analyzer.py::GeneralTestCase::test_warn_not_in_scope tests/test_analyzer.py::GeneralTestCase::test_while tests/test_analyzer.py::GeneralTestCase::test_while_no_errors tests/test_analyzer.py::GeneralTestCase::test_with_namespace tests/test_analyzer.py::GeneralTestCase::test_with_namespace_simple tests/test_analyzer.py::GeneralTestCase::test_wrong_if tests/test_analyzer.py::GeneralTestCase::test_wrong_semi_colon tests/test_analyzer.py::GeneralTestCase::test_wrong_sum tests/test_analyzer.py::PreprocessorDefine::test_define_array tests/test_analyzer.py::PreprocessorDefine::test_define_complex tests/test_analyzer.py::PreprocessorDefine::test_define_correct tests/test_analyzer.py::PreprocessorDefine::test_define_expression tests/test_analyzer.py::PreprocessorDefine::test_define_fnc tests/test_analyzer.py::PreprocessorDefine::test_define_no_error tests/test_analyzer.py::PreprocessorDefine::test_define_of_define tests/test_analyzer.py::PreprocessorDefine::test_define_replace_in_statement tests/test_analyzer.py::PreprocessorDefine::test_define_unused tests/test_analyzer.py::PreprocessorDefine::test_define_with_args_usage tests/test_analyzer.py::PreprocessorDefine::test_define_with_define tests/test_analyzer.py::PreprocessorDefine::test_defines tests/test_analyzer.py::PreprocessorDefine::test_defines_in_array tests/test_analyzer.py::PreprocessorDefine::test_defines_in_array2 tests/test_analyzer.py::PreprocessorDefine::test_defines_in_unexecuted_code tests/test_analyzer.py::PreprocessorDefine::test_defines_underscored tests/test_analyzer.py::PreprocessorDefine::test_simple tests/test_analyzer.py::Preprocessor::test_assign_to_global tests/test_analyzer.py::Preprocessor::test_assign_to_global_after_space tests/test_analyzer.py::Preprocessor::test_double_ifdef tests/test_analyzer.py::Preprocessor::test_ifdef_endif tests/test_analyzer.py::Preprocessor::test_ifdef_endif_with_defines tests/test_analyzer.py::Preprocessor::test_ifdef_with_error_in_code tests/test_analyzer.py::Preprocessor::test_ifdef_with_error_pos_in tests/test_analyzer.py::Preprocessor::test_ifdef_with_error_pos_out tests/test_analyzer.py::Preprocessor::test_include tests/test_analyzer.py::Preprocessor::test_include_error tests/test_analyzer.py::Preprocessor::test_include_error_len tests/test_analyzer.py::Preprocessor::test_include_with_semi_colon tests/test_analyzer.py::Preprocessor::test_macros tests/test_analyzer.py::Preprocessor::test_nested tests/test_analyzer.py::Preprocessor::test_same_name tests/test_analyzer.py::Preprocessor::test_sequential tests/test_analyzer.py::Preprocessor::test_some_cases tests/test_analyzer.py::Preprocessor::test_undef_else tests/test_analyzer.py::Preprocessor::test_undef_else_2 tests/test_analyzer.py::Preprocessor::test_undefined_define_with_space tests/test_analyzer.py::Preprocessor::test_upper_cased_keywords tests/test_analyzer.py::Arrays::test_array_from_function tests/test_analyzer.py::Arrays::test_basic tests/test_analyzer.py::Arrays::test_error_inside_array tests/test_analyzer.py::Arrays::test_no_space tests/test_analyzer.py::Arrays::test_position_of_array tests/test_analyzer.py::Arrays::test_strange tests/test_analyzer.py::Switch::test_case_by_variable tests/test_analyzer.py::Switch::test_case_not_code tests/test_analyzer.py::Switch::test_case_with_variable_code tests/test_analyzer.py::Switch::test_default tests/test_analyzer.py::Switch::test_default_error tests/test_analyzer.py::Switch::test_error_in_case tests/test_analyzer.py::Switch::test_incomplete_case tests/test_analyzer.py::Switch::test_missing_do tests/test_analyzer.py::Switch::test_not_statement tests/test_analyzer.py::Switch::test_switch_alone tests/test_analyzer.py::Switch::test_switch_statement_without_parenthesis tests/test_analyzer.py::NestedCode::test_array tests/test_analyzer.py::NestedCode::test_array_after_then tests/test_analyzer.py::NestedCode::test_call_within tests/test_analyzer.py::NestedCode::test_call_within_this tests/test_analyzer.py::NestedCode::test_code tests/test_analyzer.py::NestedCode::test_code_with_expression tests/test_analyzer.py::NestedCode::test_code_with_if tests/test_analyzer.py::NestedCode::test_code_with_private tests/test_analyzer.py::NestedCode::test_private tests/test_analyzer.py::NestedCode::test_private_in_exitwith tests/test_analyzer.py::Params::test_array_wrong tests/test_analyzer.py::Params::test_lhs_rhs_single_var tests/test_analyzer.py::Params::test_many tests/test_analyzer.py::Params::test_many_call tests/test_analyzer.py::Params::test_missing_arg tests/test_analyzer.py::Params::test_missing_default_arg tests/test_analyzer.py::Params::test_other tests/test_analyzer.py::Params::test_params_select tests/test_analyzer.py::Params::test_rhs_larger_lhs tests/test_analyzer.py::Params::test_single tests/test_analyzer.py::Params::test_single_array tests/test_analyzer.py::Params::test_undefined_array tests/test_analyzer.py::Params::test_with_default tests/test_analyzer.py::Params::test_with_default_unused tests/test_analyzer.py::Params::test_with_empty_string tests/test_analyzer.py::Params::test_wrong_argument tests/test_analyzer.py::Params::test_wrong_array_element tests/test_analyzer.py::SpecialContext::test_code_not_executed_in_loop tests/test_analyzer.py::SpecialContext::test_double_code tests/test_analyzer.py::SpecialContext::test_for_scope tests/test_analyzer.py::SpecialContext::test_for_scope_new tests/test_analyzer.py::SpecialContext::test_foreach tests/test_analyzer.py::SpecialContext::test_insensitive__foreachindex tests/test_analyzer.py::SpecialContext::test_issue5 tests/test_analyzer.py::SpecialContext::test_select_count_apply tests/test_analyzer.py::SpecialContext::test_spawn_local_vars tests/test_analyzer.py::SpecialContext::test_spawn_thisScript tests/test_analyzer.py::SpecialContext::test_spawn_this_typing_error tests/test_analyzer.py::SpecialContext::test_try_catch tests/test_analyzer.py::UndefinedValues::test_anything tests/test_analyzer.py::UndefinedValues::test_anything_for_undecided tests/test_analyzer.py::UndefinedValues::test_array tests/test_analyzer.py::UndefinedValues::test_array2 tests/test_analyzer.py::UndefinedValues::test_assign_if tests/test_analyzer.py::UndefinedValues::test_boolean tests/test_analyzer.py::UndefinedValues::test_code_in_namespace tests/test_analyzer.py::UndefinedValues::test_delayed_execution tests/test_analyzer.py::UndefinedValues::test_for tests/test_analyzer.py::UndefinedValues::test_for1 tests/test_analyzer.py::UndefinedValues::test_forspecs tests/test_analyzer.py::UndefinedValues::test_if tests/test_analyzer.py::UndefinedValues::test_if1 tests/test_analyzer.py::UndefinedValues::test_if_else_private tests/test_analyzer.py::UndefinedValues::test_if_else_with_global tests/test_analyzer.py::UndefinedValues::test_if_then tests/test_analyzer.py::UndefinedValues::test_if_then_else tests/test_analyzer.py::UndefinedValues::test_if_then_private tests/test_analyzer.py::UndefinedValues::test_if_with_global tests/test_analyzer.py::UndefinedValues::test_if_with_private_with_scoping tests/test_analyzer.py::UndefinedValues::test_many_scopes tests/test_analyzer.py::UndefinedValues::test_many_scopes2 tests/test_analyzer.py::UndefinedValues::test_nothing_is_not_anything tests/test_analyzer.py::UndefinedValues::test_number tests/test_analyzer.py::UndefinedValues::test_private_is_nothing tests/test_analyzer.py::UndefinedValues::test_private_undefined tests/test_analyzer.py::UndefinedValues::test_string tests/test_analyzer.py::UndefinedValues::test_two_scopes tests/test_analyzer.py::UndefinedValues::test_unexecuted_code_in_namespace tests/test_analyzer.py::UndefinedValues::test_while tests/test_analyzer.py::SpecialComment::test_string1 tests/test_analyzer.py::SpecialComment::test_string2 tests/test_analyzer.py::SpecialComment::test_string2_fail tests/test_analyzer.py::SpecialComment::test_var_type tests/test_analyzer.py::SpecialComment::test_with_space tests/test_analyzer.py::UnusedVariables::test_nested tests/test_analyzer.py::UnusedVariables::test_simple tests/test_analyzer.py::UnusedVariables::test_with_globals tests/test_analyzer.py::StringAsCodeFunctions::test_configClass tests/test_analyzer.py::StringAsCodeFunctions::test_isNil tests/test_analyzer.py::StringAsCodeFunctions::test_isNil_error tests/test_analyzer.py::StringAsCodeFunctions::test_isNil_function tests/test_analyzer.py::StringAsCodeFunctions::test_isNil_undefined
sqf/analyzer.py
sqf/analyzer.py