1# Cirq modules
2
3Cirq has a modular architecture and is organized in a monorepo, all of the modules follow the same folder structure.
4Each module is structured as follows. Let's take as example a module named `cirq-example`:
5
6```
7cirq-example
8├── cirq_example
9│   ├── __init__.py
10│   ├── _version.py
11│   ├── json_resolver_cache.py
12│   └── json_test_data
13│       ├── __init__.py
14│       └── spec.py
15├── LICENSE
16├── README.rst
17├── requirements.txt
18├── setup.cfg
19└── setup.py
20```
21
22Note that typically there is only a single top level package, `cirq_example` - but there might be exceptions.
23
24Additionally, there is a metapackage "cirq" that's a completely different beast and just depends on the modules.
25This enables `pip install cirq` to have all the included modules to be installed for our users.
26
27All modules should depend on `cirq-core`, which is the central, core library for Cirq.
28
29## Packaging
30
31Each package gets published to PyPi as a separate package. To build all the wheel files locally, use
32
33```bash
34dev_tools/packaging/produce-package.sh ./dist `./dev_tools/packaging/generate-dev-version-id.sh`
35```
36
37Packages are versioned together, share the same version number, and are released together.
38
39## Setting up a new module
40
41To setup a new module follow these steps:
42
431. Create the folder structure above, copy the files based on an existing module
44    1. LICENSE should be the same
45    2. README.rst will be the documentation that appears in PyPi
46    3. setup.py should specify an `install_requires` configuration that has `cirq-core=={module.version}` at the minimum
472. Setup JSON serialization for each top level python package
48
49
50### Setting up JSON serialization
51
521. Add the `<top_level_package>/json_resolver_cache.py` file
53    ```python
54    @functools.lru_cache()  # coverage: ignore
55    def _class_resolver_dictionary() -> Dict[str, ObjectFactory]:  # coverage: ignore
56        return {}
57    ```
582. Register the resolver cache - at _the end_ of the `<top_level_package>/__init__.py`:
59    ```python
60
61    # Registers cirq_example's public classes for JSON serialization.
62    from cirq.protocols.json_serialization import _register_resolver
63    from cirq_example.json_resolver_cache import _class_resolver_dictionary
64    _register_resolver(_class_resolver_dictionary)
65
66    ```
673. Add the `<top_level_package>/json_test_data` folder with the following content:
68   1. `spec.py` contains the core test specification for JSON testing, that plugs into the central framework:
69       ```python
70       import pathlib
71       import cirq_example
72       from cirq_example.json_resolver_cache import _class_resolver_dictionary
73
74       from cirq.testing.json import ModuleJsonTestSpec
75
76       TestSpec = ModuleJsonTestSpec(
77           name="cirq_example",
78           packages=[cirq_example],
79           test_data_path=pathlib.Path(__file__).parent,
80           not_yet_serializable=[],
81           should_not_be_serialized=[],
82           resolver_cache=_class_resolver_dictionary(),
83           deprecated={},
84        )
85       ```
86   2. `__init__.py` should import `TestSpec` from `spec.py`
87   3. in `cirq/protocols/json_serialization_test.py` add `'cirq_example':None` to the `TESTED_MODULES` variable. `TESTED_MODULES` is also used to prepare the test framework for deprecation warnings.
88      With new modules, we use`None` as there is no deprecation setup.
89
90You can run `check/pytest-changed-files` and that should execute the json_serialization_test.py as well.
91
92That's it! Now, you can follow the [Serialization guide](./serialization.md) for adding and removing serializable objects.
93
94# Utilities
95
96## List modules
97
98To iterate through modules, you can list them by invoking `dev_tools/modules.py`.
99
100```bash
101python dev_tools/modules.py --list
102```
103
104There are different modes of listing (e.g the folder, package-path, top level package),
105you can refer to `python dev_tools/modules.py --list --help` for the most up to date features.
106