francoisfreitag: I think both commits can be squashed.
diff --git a/factory/declarations.py b/factory/declarations.py
index bdb44ab..18c1fd5 100644
--- a/factory/declarations.py
+++ b/factory/declarations.py
@@ -444,6 +444,15 @@ SKIP = Skip()
 class Maybe(BaseDeclaration):
     def __init__(self, decider, yes_declaration=SKIP, no_declaration=SKIP):
         super(Maybe, self).__init__()
+
+        if enums.get_builder_phase(decider) is None:
+            # No builder phase => flat value
+            decider = SelfAttribute(decider, default=None)
+
+        self.decider = decider
+        self.yes = yes_declaration
+        self.no = no_declaration
+
         phases = {
             'yes_declaration': enums.get_builder_phase(yes_declaration),
             'no_declaration': enums.get_builder_phase(no_declaration),
@@ -455,14 +464,6 @@ class Maybe(BaseDeclaration):
 
         self.FACTORY_BUILDER_PHASE = used_phases.pop() if used_phases else enums.BuilderPhase.ATTRIBUTE_RESOLUTION
 
-        if enums.get_builder_phase(decider) is None:
-            # No builder phase => flat value
-            decider = SelfAttribute(decider, default=None)
-
-        self.decider = decider
-        self.yes = yes_declaration
-        self.no = no_declaration
-
     def call(self, instance, step, context):
         decider_phase = enums.get_builder_phase(self.decider)
         if decider_phase == enums.BuilderPhase.ATTRIBUTE_RESOLUTION:

Maybe: Inconsistent phases TypeError masked by __repr__ AttributeError 
#### Description
The TypeError check in `declarations.Maybe.__init__` is masked by an AttributeError because the TypeError error message uses `__repr__` which in turn uses `self` attributes that haven't yet be set in `__init__`.

#### To Reproduce
Noticed when upgrading from `2.8.1` to `2.12.0` on a factory that used Traits and had a PostGeneration hook which resulted in a Maybe object with a yes declaration evaluating to a List object (`attributes` enum) and a no declaration evaluating to a PostGeneration object (`post_instance` enum).

To reproduce: Create a `Maybe` object with yes/no declarations with differing enums. 

##### Model / Factory code
Minimal example

```python
In [1]: from factory.declarations import LazyAttribute, Maybe, PostGenerationDeclaration

In [2]: Maybe(None, LazyAttribute(None), PostGenerationDeclaration())

AttributeError                            Traceback (most recent call last)
----> 1 Maybe(None, LazyAttribute(None), PostGenerationDeclaration())

~/venv/lib/python3.6/site-packages/factory/declarations.py in __init__(self, decider, yes_declaration, no_declaration)
    456
    457         if len(used_phases) > 1:
--> 458             raise TypeError("Inconsistent phases for %r: %r" % (self, phases))
    459
    460         self.FACTORY_BUILDER_PHASE = used_phases.pop() if used_phases else enums.BuilderPhase.ATTRIBUTE_RESOLUTION

~/venv/lib/python3.6/site-packages/factory/declarations.py in __repr__(self)
    504
    505     def __repr__(self):
--> 506         return 'Maybe(%r, yes=%r, no=%r)' % (self.decider, self.yes, self.no)
    507
    508

AttributeError: 'Maybe' object has no attribute 'decider'
```

##### The issue
The TypeError error message uses `self` but the `__repr__` uses attributes that only get set on `self` at the end of `__init__`. This raises an AttributeError which masks the actual TypeError.

If the attributes were set ahead of the check on https://github.com/FactoryBoy/factory_boy/blob/master/factory/declarations.py#L454 then the expected exception would be raised:

```python
In [1]: from factory.declarations import LazyAttribute, Maybe, PostGenerationDeclaration

In [2]: Maybe(None, LazyAttribute(None), PostGenerationDeclaration())

TypeError                                 Traceback (most recent call last)
/vagrant/.konchrc in <module>
----> 1 Maybe(None, LazyAttribute(None), PostGenerationDeclaration())

~/venv/lib/python3.6/site-packages/factory/declarations.py in __init__(self, decider, yes_declaration, no_declaration)
    460
    461         if len(used_phases) > 1:
--> 462             raise TypeError("Inconsistent phases for %r: %r" % (self, phases))
    463
    464         self.FACTORY_BUILDER_PHASE = used_phases.pop() if used_phases else enums.BuilderPhase.ATTRIBUTE_RESOLUTION

TypeError: Inconsistent phases for Maybe(None, yes=<factory.declarations.LazyAttribute object at 0x7f0ec15d4d30>, no=<factory.declarations.PostGenerationDeclaration object at 0x7f0ec15d4160>): {'yes_declaration': 'attributes', 'no_declaration': 'post_instance'}
```

#### Notes

Check was introduced in 33d27c219044
diff --git a/tests/test_declarations.py b/tests/test_declarations.py
index 889080a..2e6474d 100644
--- a/tests/test_declarations.py
+++ b/tests/test_declarations.py
@@ -43,6 +43,21 @@ class DigTestCase(unittest.TestCase):
         self.assertEqual(42, declarations.deepgetattr(obj, 'a.b.c.n.x', 42))
 
 
+class MaybeTestCase(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        # remove after dropping python 2
+        import sys
+        if int(sys.version[0]) == 2:
+            cls.assertRaisesRegex = cls.assertRaisesRegexp
+
+    def test_init(self):
+        declarations.Maybe('foo', 1, 2)
+
+        with self.assertRaisesRegex(TypeError, 'Inconsistent phases'):
+            declarations.Maybe('foo', declarations.LazyAttribute(None), declarations.PostGenerationDeclaration())
+
+
 class SelfAttributeTestCase(unittest.TestCase):
     def test_standard(self):
         a = declarations.SelfAttribute('foo.bar.baz')

pip install -e .
parse_log_pytest
requirements.txt
pytest
3.7
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi @ file:///croot/certifi_1671487769961/work/certifi
exceptiongroup==1.2.2
-e git+https://github.com/FactoryBoy/factory_boy.git@4d2aca14723126adf47f1482c3c9f2f0e662debe#egg=factory_boy
Faker==18.13.0
importlib-metadata==6.7.0
iniconfig==2.0.0
packaging==24.0
pluggy==1.2.0
pytest==7.4.4
python-dateutil==2.9.0.post0
six==1.17.0
tomli==2.0.1
typing_extensions==4.7.1
zipp==3.15.0

name: factory_boy
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
  - certifi=2022.12.7=py37h06a4308_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=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - exceptiongroup==1.2.2
      - faker==18.13.0
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - packaging==24.0
      - pluggy==1.2.0
      - pytest==7.4.4
      - python-dateutil==2.9.0.post0
      - six==1.17.0
      - tomli==2.0.1
      - typing-extensions==4.7.1
      - zipp==3.15.0
prefix: /opt/conda/envs/factory_boy

tests/test_declarations.py::MaybeTestCase::test_init
tests/test_declarations.py::OrderedDeclarationTestCase::test_errors tests/test_declarations.py::DigTestCase::test_chaining tests/test_declarations.py::SelfAttributeTestCase::test_default tests/test_declarations.py::SelfAttributeTestCase::test_dot tests/test_declarations.py::SelfAttributeTestCase::test_grandparent tests/test_declarations.py::SelfAttributeTestCase::test_parent tests/test_declarations.py::SelfAttributeTestCase::test_standard tests/test_declarations.py::IteratorTestCase::test_cycle tests/test_declarations.py::IteratorTestCase::test_getter tests/test_declarations.py::IteratorTestCase::test_initial_reset tests/test_declarations.py::IteratorTestCase::test_no_cycling tests/test_declarations.py::IteratorTestCase::test_reset_cycle tests/test_declarations.py::IteratorTestCase::test_reset_no_cycling tests/test_declarations.py::PostGenerationDeclarationTestCase::test_decorator_simple tests/test_declarations.py::PostGenerationDeclarationTestCase::test_post_generation tests/test_declarations.py::FactoryWrapperTestCase::test_cache tests/test_declarations.py::FactoryWrapperTestCase::test_class tests/test_declarations.py::FactoryWrapperTestCase::test_invalid_path tests/test_declarations.py::FactoryWrapperTestCase::test_lazyness tests/test_declarations.py::FactoryWrapperTestCase::test_path tests/test_declarations.py::PostGenerationMethodCallTestCase::test_call_with_method_args tests/test_declarations.py::PostGenerationMethodCallTestCase::test_call_with_method_kwargs tests/test_declarations.py::PostGenerationMethodCallTestCase::test_call_with_passed_extracted_int tests/test_declarations.py::PostGenerationMethodCallTestCase::test_call_with_passed_extracted_iterable tests/test_declarations.py::PostGenerationMethodCallTestCase::test_call_with_passed_extracted_string tests/test_declarations.py::PostGenerationMethodCallTestCase::test_call_with_passed_kwargs tests/test_declarations.py::PostGenerationMethodCallTestCase::test_multi_call_with_multi_method_args tests/test_declarations.py::PostGenerationMethodCallTestCase::test_simplest_setup_and_call tests/test_declarations.py::PostGenerationOrdering::test_post_generation_declaration_order
factory/declarations.py
factory/declarations.py