mergeron 2025.739290.1__py3-none-any.whl → 2025.739290.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mergeron might be problematic. Click here for more details.

mergeron/__init__.py CHANGED
@@ -12,7 +12,7 @@ from ruamel import yaml
12
12
 
13
13
  _PKG_NAME: str = Path(__file__).parent.stem
14
14
 
15
- VERSION = "2025.739290.1"
15
+ VERSION = "2025.739290.3"
16
16
 
17
17
  __version__ = VERSION
18
18
 
@@ -8,13 +8,16 @@ Reported row and column totals from source data are not stored.
8
8
 
9
9
  """
10
10
 
11
+ from __future__ import annotations
12
+
11
13
  import shutil
12
14
  from collections.abc import Mapping, Sequence
15
+ from dataclasses import dataclass
13
16
  from importlib import resources
14
17
  from operator import itemgetter
15
18
  from pathlib import Path
16
19
  from types import MappingProxyType
17
- from typing import Any, NamedTuple
20
+ from typing import Any
18
21
 
19
22
  import msgpack # type: ignore
20
23
  import msgpack_numpy as m # type: ignore
@@ -23,8 +26,9 @@ import re2 as re # type: ignore
23
26
  import urllib3
24
27
  from bs4 import BeautifulSoup
25
28
  from numpy.testing import assert_array_equal
29
+ from ruamel import yaml
26
30
 
27
- from .. import _PKG_NAME, DATA_DIR, VERSION, ArrayBIGINT # noqa: TID252
31
+ from .. import _PKG_NAME, DATA_DIR, EMPTY_ARRAYINT, VERSION, ArrayBIGINT # noqa: TID252
28
32
 
29
33
  __version__ = VERSION
30
34
 
@@ -89,11 +93,27 @@ CNT_FCOUNT_DICT = {
89
93
  }
90
94
 
91
95
 
92
- class INVTableData(NamedTuple):
96
+ @dataclass(slots=True, frozen=True)
97
+ class INVTableData:
93
98
  industry_group: str
94
99
  additional_evidence: str
95
100
  data_array: ArrayBIGINT
96
101
 
102
+ @classmethod
103
+ def to_yaml(
104
+ cls, _r: yaml.representer.SafeRepresenter, _d: INVTableData
105
+ ) -> yaml.MappingNode:
106
+ _ret: yaml.MappingNode = _r.represent_mapping(
107
+ f"!{cls.__name__}", {_a: getattr(_d, _a) for _a in _d.__dataclass_fields__}
108
+ )
109
+ return _ret
110
+
111
+ @classmethod
112
+ def from_yaml(
113
+ cls, _c: yaml.constructor.SafeConstructor, _n: yaml.MappingNode
114
+ ) -> INVTableData:
115
+ return cls(**_c.construct_mapping(_n))
116
+
97
117
 
98
118
  type INVData = Mapping[str, Mapping[str, Mapping[str, INVTableData]]]
99
119
  type _INVData_in = dict[str, dict[str, dict[str, INVTableData]]]
@@ -278,10 +298,13 @@ def _construct_new_period_data(
278
298
  _invdata_cuml_sub_table.data_array,
279
299
  )
280
300
 
281
- _invdata_base_sub_table = _invdata_base[_table_type].get(_table_no, None)
301
+ _invdata_base_sub_table = _invdata_base[_table_type].get(
302
+ _table_no, INVTableData("", "", EMPTY_ARRAYINT)
303
+ )
282
304
 
283
305
  (_invdata_base_ind_group, _invdata_base_evid_cond, _invdata_base_array) = (
284
- _invdata_base_sub_table or ("", "", None)
306
+ getattr(_invdata_base_sub_table, _a)
307
+ for _a in ("industry_group", "additional_evidence", "data_array")
285
308
  )
286
309
 
287
310
  # Some tables can't be constructed due to inconsistencies in the data
@@ -43,6 +43,21 @@ class HMGThresholds:
43
43
  cmcr: float
44
44
  ipr: float
45
45
 
46
+ @classmethod
47
+ def to_yaml(
48
+ cls, _r: yaml.representer.SafeRepresenter, _d: HMGThresholds
49
+ ) -> yaml.MappingNode:
50
+ _ret: yaml.MappingNode = _r.represent_mapping(
51
+ f"!{cls.__name__}", {_a: getattr(_d, _a) for _a in _d.__dataclass_fields__}
52
+ )
53
+ return _ret
54
+
55
+ @classmethod
56
+ def from_yaml(
57
+ cls, _c: yaml.constructor.SafeConstructor, _n: yaml.MappingNode
58
+ ) -> HMGThresholds:
59
+ return cls(**_c.construct_mapping(_n))
60
+
46
61
 
47
62
  @this_yaml.register_class
48
63
  @frozen
mergeron/gen/__init__.py CHANGED
@@ -40,7 +40,7 @@ __version__ = VERSION
40
40
  DEFAULT_FCOUNT_WTS = np.asarray((_nr := np.arange(6, 0, -1)) / _nr.sum(), float)
41
41
 
42
42
 
43
- @dataclass
43
+ @dataclass(slots=True, frozen=True)
44
44
  class SeedSequenceData:
45
45
  share: SeedSequence
46
46
  pcm: SeedSequence
@@ -654,3 +654,20 @@ for _typ in (
654
654
  ),
655
655
  ),
656
656
  )
657
+
658
+ for _typ in (MarketSampleData, SeedSequenceData, UPPTestsCounts):
659
+ _, _ = (
660
+ this_yaml.representer.add_representer(
661
+ _typ,
662
+ lambda _r, _d: _r.represent_mapping(
663
+ f"!{_d.__class__.__name__}",
664
+ {_a: getattr(_d, _a) for _a in _d.__dataclass_fields__},
665
+ ),
666
+ ),
667
+ this_yaml.constructor.add_constructor(
668
+ _typ,
669
+ lambda _c, _n: globals().get(
670
+ _n.tag.lstrip("!")(**_c.construct_mapping(_n))
671
+ ),
672
+ ),
673
+ )
@@ -46,8 +46,8 @@ def gen_share_data(
46
46
  _sample_size: int,
47
47
  _share_spec: ShareSpec,
48
48
  _fcount_rng_seed_seq: SeedSequence | None,
49
- _mktshr_rng_seed_seq: SeedSequence | None = None,
50
- _nthreads: int = NTHREADS,
49
+ _mktshr_rng_seed_seq: SeedSequence,
50
+ _nthreads: int,
51
51
  /,
52
52
  ) -> ShareDataSample:
53
53
  """Helper function for generating share data.
@@ -69,9 +69,9 @@ def gen_share_data(
69
69
 
70
70
  """
71
71
 
72
- _recapture_form, _dist_type_mktshr, _dist_parms_mktshr, _firm_count_prob_wts = (
72
+ _dist_type_mktshr, _firm_count_prob_wts, _dist_parms_mktshr, _recapture_form = (
73
73
  getattr(_share_spec, _f)
74
- for _f in ("recapture_form", "dist_type", "dist_parms", "firm_counts_weights")
74
+ for _f in ("dist_type", "firm_counts_weights", "dist_parms", "recapture_form")
75
75
  )
76
76
 
77
77
  _ssz = _sample_size
@@ -126,8 +126,8 @@ def gen_share_data(
126
126
  def gen_market_shares_uniform(
127
127
  _s_size: int,
128
128
  _dist_parms_mktshr: ArrayDouble,
129
- _mktshr_rng_seed_seq: SeedSequence | None = None,
130
- _nthreads: int = NTHREADS,
129
+ _mktshr_rng_seed_seq: SeedSequence,
130
+ _nthreads: int,
131
131
  /,
132
132
  ) -> ShareDataSample:
133
133
  """Generate merging-firm shares from Uniform distribution on the 3-D simplex.
@@ -159,13 +159,12 @@ def gen_market_shares_uniform(
159
159
  nthreads=_nthreads,
160
160
  )
161
161
  _mrng.fill()
162
- # Convert draws on U[0, 1] to Uniformly-distributed draws on simplex, s_1 + s_2 <= 1
163
- _frmshr_array.sort(axis=1)
164
162
 
165
- _frmshr_array = np.array(
166
- (_frmshr_array[:, 0], _frmshr_array[:, 1] - _frmshr_array[:, 0]),
167
- _frmshr_array.dtype,
168
- ).T # faster than np.stack() and variants
163
+ # Convert draws on U[0, 1] to Uniformly-distributed draws on simplex, s_1 + s_2 <= 1
164
+ _frmshr_array = np.hstack((
165
+ _frmshr_array.min(axis=1, keepdims=True),
166
+ np.abs(np.diff(_frmshr_array, axis=1)),
167
+ ))
169
168
 
170
169
  # Keep only share combinations representing feasible mergers
171
170
  # This is a no-op for 64-bit floats, but is necessary for smaller floats
@@ -199,8 +198,8 @@ def _gen_market_shares_dirichlet_multimarket(
199
198
  _dist_type_dir: SHRDistribution,
200
199
  _dist_parms_dir: ArrayDouble,
201
200
  _firm_count_wts: ArrayDouble,
202
- _fcount_rng_seed_seq: SeedSequence | None = None,
203
- _mktshr_rng_seed_seq: SeedSequence | None = None,
201
+ _fcount_rng_seed_seq: SeedSequence | None,
202
+ _mktshr_rng_seed_seq: SeedSequence,
204
203
  _nthreads: int = NTHREADS,
205
204
  /,
206
205
  ) -> ShareDataSample:
@@ -341,8 +340,8 @@ def gen_market_shares_dirichlet(
341
340
  _dir_alphas: ArrayDouble,
342
341
  _s_size: int,
343
342
  _recapture_form: RECForm,
344
- _mktshr_rng_seed_seq: SeedSequence | None = None,
345
- _nthreads: int = NTHREADS,
343
+ _mktshr_rng_seed_seq: SeedSequence,
344
+ _nthreads: int,
346
345
  /,
347
346
  ) -> ShareDataSample:
348
347
  """Dirichlet-distributed shares with fixed firm-count.
@@ -497,7 +496,7 @@ def gen_margin_price_data(
497
496
  _hsr_filing_test_type: SSZConstant,
498
497
  _pcm_rng_seed_seq: SeedSequence,
499
498
  _pr_rng_seed_seq: SeedSequence | None,
500
- _nthreads: int = NTHREADS,
499
+ _nthreads: int,
501
500
  /,
502
501
  ) -> tuple[MarginDataSample, PriceDataSample]:
503
502
  """Generate margin and price data for mergers in the sample.
@@ -680,8 +679,8 @@ def _gen_margin_data(
680
679
  _price_array: ArrayDouble,
681
680
  _aggregate_purchase_prob: ArrayDouble,
682
681
  _pcm_spec: PCMSpec,
683
- _pcm_rng_seed_seq: SeedSequence | None,
684
- _nthreads: int = NTHREADS,
682
+ _pcm_rng_seed_seq: SeedSequence,
683
+ _nthreads: int,
685
684
  /,
686
685
  ) -> MarginDataSample:
687
686
  _dist_type_pcm, _dist_firm2_pcm, _dist_parms_pcm = (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mergeron
3
- Version: 2025.739290.1
3
+ Version: 2025.739290.3
4
4
  Summary: Analyze merger enforcement policy using Python
5
5
  License: MIT
6
6
  Keywords: merger policy analysis,merger guidelines,merger screening,policy presumptions,concentration standards,upward pricing pressure,GUPPI
@@ -1,8 +1,8 @@
1
- mergeron/__init__.py,sha256=fxabxjXrodvYcQtmpl6jv21ZGl-RPBI18ECzPQ60MPY,3515
1
+ mergeron/__init__.py,sha256=LOHcLKtaYWz9mCtT37NNkZrHrHF6G3IPqfxMc30UdJY,3515
2
2
  mergeron/core/__init__.py,sha256=qYRA1D4Gx-WSkICqiueWLWPedkWmb_CIn7fgvN7unk4,182
3
3
  mergeron/core/empirical_margin_distribution.py,sha256=byO11ROGVQcmbZVWdVJkJ906WnHhx7jcoL5BbxPmX7I,8688
4
- mergeron/core/ftc_merger_investigations_data.py,sha256=9AT-phfkn0NHJvn9lcpbH8ExWZStYW47KQjNjDGS3qc,28709
5
- mergeron/core/guidelines_boundaries.py,sha256=4twCwb7see2nbBV5wSKPg-Let9huex3CxqgAY-JG-2g,17239
4
+ mergeron/core/ftc_merger_investigations_data.py,sha256=13yEg7L3wpR2XU4v7WAfSH-lIDk0eRv31i0LY39Fk4w,29452
5
+ mergeron/core/guidelines_boundaries.py,sha256=1d-ToNnX-lQpcj4ucfxwwa9Vu2dcQTx8DPJKEZ7SmEM,17723
6
6
  mergeron/core/guidelines_boundary_functions.py,sha256=4vMz5DQ72fgj7leUlVJvXBrxdZAeDJP7FoGBEVXDdeQ,34866
7
7
  mergeron/core/guidelines_boundary_functions_extra.py,sha256=qL1zT-Xgj2qD2EyBRR87APoVc47MkGM02xYQhNgwEvg,11216
8
8
  mergeron/core/pseudorandom_numbers.py,sha256=8_MBHIvWjVZUN4Et7Tt3J1NzWxuzq9vtzFkycW5rBaQ,9918
@@ -12,12 +12,12 @@ mergeron/data/damodaran_margin_data_dict.msgpack,sha256=sr6s4L69kposEpzGI7jpPb4U
12
12
  mergeron/data/ftc_invdata.msgpack,sha256=WBFHgi7Ld4R-h2zL2Zc3TOIlKqVrbVFMH1LoI4-T-M0,264664
13
13
  mergeron/demo/__init__.py,sha256=KtjBlZOl7jwBCAUhrTJB9PdrN39YLYytNiSUSM_gRmA,62
14
14
  mergeron/demo/visualize_empirical_margin_distribution.py,sha256=kDwPfhsBjsQdYPyhe4KZG2guB_xHhPaCrvn8fezIz4M,2354
15
- mergeron/gen/__init__.py,sha256=t1RswXk-L6olOhj5XqPekd8je8Za7NUFuSo3fuM2Wts,21787
15
+ mergeron/gen/__init__.py,sha256=Y_7KBS4YHaFZO9P8phE-pAyhV6eA2a1bGUtfy7c2cfs,22352
16
16
  mergeron/gen/data_generation.py,sha256=IBWo-Al2ApHnjVQyIUV35x0OnoMgliJfqy5YrbBCVgo,16101
17
- mergeron/gen/data_generation_functions.py,sha256=LwqbCYSqK2PfFrHhZaTOaF7UtlsVnhm0Ykmfgf3P-G4,27187
17
+ mergeron/gen/data_generation_functions.py,sha256=RqPTjCAyYJkOvbLdbgnBJUFJ7ecE1UvPB1rvBhfimy0,26988
18
18
  mergeron/gen/enforcement_stats.py,sha256=z_Kjw1OwLue5B-tKFlmEoyGDusi9D6c77foRCmiNGqQ,11532
19
19
  mergeron/gen/upp_tests.py,sha256=VTh0rDd0cJ70MwkvRDYx27LWMaA1BPThXfd3D1HKX-E,12489
20
20
  mergeron/py.typed,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
21
- mergeron-2025.739290.1.dist-info/METADATA,sha256=Y7cBEZaZAuOWsdpYKSQjNOjebKCGtYLO1nz8AEwDGFE,14541
22
- mergeron-2025.739290.1.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
23
- mergeron-2025.739290.1.dist-info/RECORD,,
21
+ mergeron-2025.739290.3.dist-info/METADATA,sha256=r7BI1s7ThvmlPwnf-WJuHJ2-PS_6oTl6ub7M6oC32hE,14541
22
+ mergeron-2025.739290.3.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
23
+ mergeron-2025.739290.3.dist-info/RECORD,,