Skip to content

Fix PropertyLayer default value type mismatch warnings#2963

Merged
EwoutH merged 15 commits intomesa:mainfrom
falloficarus22:fix-propertylayer-default-value-type-mismatch
Dec 21, 2025
Merged

Fix PropertyLayer default value type mismatch warnings#2963
EwoutH merged 15 commits intomesa:mainfrom
falloficarus22:fix-propertylayer-default-value-type-mismatch

Conversation

@falloficarus22
Copy link
Copy Markdown
Contributor

@falloficarus22 falloficarus22 commented Dec 17, 2025

Summary

Fixed false warnings in PropertyLayer when default_value is compatible with the specified dtype. The previous implementation used isinstance() checks that incorrectly flagged compatible values (e.g., float 10.0 with dtype=float or np.float64) as type mismatches. This fix eliminates ~4 false warnings in test files while maintaining proper warnings for actual incompatibilities and precision loss cases.

Bug / Issue

The PropertyLayer class was generating false UserWarning messages about dtype mismatches when the default_value was actually compatible with the specified dtype. This occurred because:

  1. Root Cause: The code used isinstance(default_value, dtype) which doesn't work correctly with NumPy dtypes. For example:

    • isinstance(10.0, float) returns True (correct)
    • isinstance(10.0, np.float64) returns False (incorrect, even though 10.0 is compatible)
  2. Impact: This caused false warnings in multiple test files:

    • tests/test_space_renderer.py:46 - PropertyLayer("test", [2, 2], default_value=0, dtype=int)
    • tests/test_solara_viz.py:121 - PropertyLayer(..., default_value=10.0, dtype=float)
    • tests/test_solara_viz_updated.py:136 - PropertyLayer(..., default_value=10.0, dtype=float)
    • tests/test_components_matplotlib.py:240 - PropertyLayer(..., default_value=0, dtype=int)
  3. Expected Behavior: Warnings should only appear for actual incompatibilities (e.g., string -> int) or precision loss (e.g., 10.5 -> int).

Implementation

Replaced the isinstance()-based type checking with NumPy-aware dtype compatibility checking in both PropertyLayer implementations:

Files Modified:

  • mesa/discrete_space/property_layer.py
  • mesa/space.py
  • tests/test_discrete_space.py

Key Changes:

  1. Dtype Normalization: Use np.dtype(dtype) to normalize both Python types (int, float) and NumPy types (np.int64, np.float64) to NumPy dtype objects.

  2. Conversion Testing: Instead of type checking, attempt actual conversion using np.array([default_value], dtype=dtype_obj) to verify compatibility.

  3. Precision Loss Detection: Added specific check for precision loss when converting float -> int with decimal values (e.g., 10.5 -> int).

  4. Error Handling: Only warn when conversion fails (ValueError, TypeError, OverflowError) or when precision would be lost.

Testing

Manual Testing:
Created and ran test cases to verify the fix works correctly:

  1. default_value=0, dtype=int -> No warning (compatible)
  2. default_value=10.0, dtype=float -> No warning (compatible)
  3. default_value=0, dtype=float -> No warning (compatible)
  4. default_value=10.0, dtype=np.float64 -> No warning (compatible)
  5. default_value=0, dtype=np.int64 -> No warning (compatible)
  6. default_value=10.5, dtype=int -> Warns correctly (precision loss)

Affected Test Files:
The following test files should no longer generate false warnings:

  • tests/test_space_renderer.py:46
  • tests/test_solara_viz.py:121
  • tests/test_solara_viz_updated.py:136
  • tests/test_components_matplotlib.py:240

Verification:

  • Code passes linting checks (no errors)
  • Logic verified with direct dtype compatibility tests
  • Both PropertyLayer implementations fixed consistently

Additional Notes

  • Backward Compatibility: This change is fully backward compatible. It only affects when warnings are raised, not the actual functionality of PropertyLayer.
  • Consistency: Both PropertyLayer implementations (mesa.space.PropertyLayer and mesa.discrete_space.PropertyLayer) were updated to use the same logic for consistency.
  • Future Considerations: The fix properly handles both Python native types and NumPy types, making it more robust for users who prefer explicit NumPy dtypes.
  • Related: This addresses the "PropertyLayer Default Value Type Mismatch" warnings mentioned in Tracking issue: Resolve test suite warnings #2904 (section 2.2)

falloficarus22 and others added 2 commits December 17, 2025 10:32
Replace isinstance() check with NumPy-aware dtype compatibility
checking. The previous implementation incorrectly warned when
default_value was compatible with the dtype (e.g., float 10.0
with dtype=float or np.float64).

The fix normalizes dtypes using np.dtype() to handle both Python
types (int, float) and NumPy types (np.int64, np.float64), and
tests actual conversion instead of type checking. Warnings are
now only raised for actual incompatibilities or precision loss.

Fixes false warnings in:
- tests/test_space_renderer.py
- tests/test_solara_viz.py
- tests/test_solara_viz_updated.py
- tests/test_components_matplotlib.py
@github-actions
Copy link
Copy Markdown

Performance benchmarks:

Model Size Init time [95% CI] Run time [95% CI]
BoltzmannWealth small 🔵 -1.6% [-2.4%, -0.8%] 🔵 -0.1% [-0.2%, +0.0%]
BoltzmannWealth large 🔵 +2.0% [+0.1%, +5.3%] 🔵 -0.1% [-1.8%, +1.6%]
Schelling small 🔵 -0.2% [-1.2%, +0.9%] 🔵 -1.4% [-2.0%, -0.9%]
Schelling large 🔵 -0.4% [-3.8%, +3.0%] 🔵 -2.8% [-3.2%, -2.4%]
WolfSheep small 🔵 -2.5% [-4.0%, -1.1%] 🔵 -0.3% [-0.5%, -0.2%]
WolfSheep large 🔵 +0.2% [-0.2%, +0.7%] 🔵 +0.1% [-0.8%, +1.2%]
BoidFlockers small 🔵 -1.4% [-1.8%, -1.0%] 🔵 -0.4% [-0.6%, -0.3%]
BoidFlockers large 🔵 -2.0% [-2.5%, -1.5%] 🔵 -1.0% [-1.1%, -0.8%]

falloficarus22 and others added 2 commits December 17, 2025 11:16
Replace isinstance() check with NumPy-aware dtype compatibility
checking. The previous implementation incorrectly warned when
default_value was compatible with the dtype (e.g., float 10.0
with dtype=float or np.float64).

The fix normalizes dtypes using np.dtype() to handle both Python
types (int, float) and NumPy types (np.int64, np.float64), and
tests actual conversion instead of type checking. Warnings are
now only raised for actual incompatibilities or precision loss.

Fixes false warnings in:
- tests/test_space_renderer.py:46
- tests/test_solara_viz.py:121
- tests/test_solara_viz_updated.py:136
- tests/test_components_matplotlib.py:240

Updated test_discrete_space.py::test_property_layer_errors to
test a legitimate warning case (precision loss) instead of a
false positive.
Copy link
Copy Markdown
Member

@quaquel quaquel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have 2 questions, but looks fine to me otherwise

@falloficarus22 falloficarus22 force-pushed the fix-propertylayer-default-value-type-mismatch branch from f5ddfad to 1936cf8 Compare December 18, 2025 10:52
@quaquel
Copy link
Copy Markdown
Member

quaquel commented Dec 18, 2025

Can you also check why builds are failing now?

@falloficarus22
Copy link
Copy Markdown
Contributor Author

Can you also check why builds are failing now?

I need to update tests, working on it.

falloficarus22 and others added 3 commits December 18, 2025 11:22
Replace isinstance() check with NumPy-aware dtype compatibility
checking. The previous implementation incorrectly warned when
default_value was compatible with the dtype (e.g., float 10.0
with dtype=float or np.float64).

The fix normalizes dtypes using np.dtype() to handle both Python
types (int, float) and NumPy types (np.int64, np.float64), and
tests actual conversion instead of type checking. Warnings are
now only raised for actual incompatibilities or precision loss.

Fixes false warnings in:
- tests/test_space_renderer.py
- tests/test_solara_viz.py
- tests/test_solara_viz_updated.py
- tests/test_components_matplotlib.py
@falloficarus22 falloficarus22 force-pushed the fix-propertylayer-default-value-type-mismatch branch from 11ba09e to bf08639 Compare December 18, 2025 11:41
Refactored the dtype validation logic to be more concise and readable:
- Reduced code from ~20 lines to ~8 lines per location
- Removed intermediate np.dtype() wrapper and array creation
- Simplified precision loss detection using direct type conversion
- Maintained all functionality: incompatible types raise TypeError,
  precision loss triggers UserWarning

The new implementation uses dtype(default_value) directly and compares
the result to detect any conversion issues, making the logic clearer
and eliminating code duplication between property_layer.py and space.py.
@EwoutH EwoutH added testing Release notes label maintenance Release notes label labels Dec 21, 2025
Copy link
Copy Markdown
Member

@EwoutH EwoutH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made a few modifications to reduce the complexity.

The current dtype system is not ideal, we might want to handle that differently (automatically) in the future.

Thanks!

@EwoutH EwoutH merged commit 45da61e into mesa:main Dec 21, 2025
15 checks passed
@falloficarus22 falloficarus22 deleted the fix-propertylayer-default-value-type-mismatch branch December 22, 2025 03:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintenance Release notes label testing Release notes label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants