ion-CSP 2.0.4__tar.gz → 2.0.8__tar.gz

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.
Files changed (75) hide show
  1. {ion_csp-2.0.4 → ion_csp-2.0.8}/.github/workflows/build.yml +4 -5
  2. ion_csp-2.0.8/.github/workflows/python-package-conda.yml +47 -0
  3. {ion_csp-2.0.4 → ion_csp-2.0.8}/.github/workflows/python-publish.yml +3 -0
  4. {ion_csp-2.0.4 → ion_csp-2.0.8}/.gitignore +3 -0
  5. {ion_csp-2.0.4 → ion_csp-2.0.8}/PKG-INFO +3 -3
  6. {ion_csp-2.0.4 → ion_csp-2.0.8}/README.md +2 -2
  7. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/__init__.py +2 -2
  8. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/read_mlp_density.py +47 -3
  9. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/task_manager.py +11 -8
  10. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP.egg-info/PKG-INFO +3 -3
  11. ion_csp-2.0.4/.github/workflows/python-package-conda.yml +0 -43
  12. {ion_csp-2.0.4 → ion_csp-2.0.8}/.dockerignore +0 -0
  13. {ion_csp-2.0.4 → ion_csp-2.0.8}/.vscode/settings.json +0 -0
  14. {ion_csp-2.0.4 → ion_csp-2.0.8}/CHANGELOG.md +0 -0
  15. {ion_csp-2.0.4 → ion_csp-2.0.8}/CODE_OF_CONDUCT.md +0 -0
  16. {ion_csp-2.0.4 → ion_csp-2.0.8}/CONTRIBUTING.md +0 -0
  17. {ion_csp-2.0.4 → ion_csp-2.0.8}/Dockerfile +0 -0
  18. {ion_csp-2.0.4 → ion_csp-2.0.8}/LICENSE +0 -0
  19. {ion_csp-2.0.4 → ion_csp-2.0.8}/MANIFEST.in +0 -0
  20. {ion_csp-2.0.4 → ion_csp-2.0.8}/SECURITY.md +0 -0
  21. {ion_csp-2.0.4 → ion_csp-2.0.8}/docs/example_usage_CSP.py +0 -0
  22. {ion_csp-2.0.4 → ion_csp-2.0.8}/docs/example_usage_EE.py +0 -0
  23. {ion_csp-2.0.4 → ion_csp-2.0.8}/docs/index.md +0 -0
  24. {ion_csp-2.0.4 → ion_csp-2.0.8}/docs/usage.md +0 -0
  25. {ion_csp-2.0.4 → ion_csp-2.0.8}/environment.yml +0 -0
  26. {ion_csp-2.0.4 → ion_csp-2.0.8}/examples/example_usage.py +0 -0
  27. {ion_csp-2.0.4 → ion_csp-2.0.8}/makefile +0 -0
  28. {ion_csp-2.0.4 → ion_csp-2.0.8}/model/model.pt +0 -0
  29. {ion_csp-2.0.4 → ion_csp-2.0.8}/model/options/README.md +0 -0
  30. {ion_csp-2.0.4 → ion_csp-2.0.8}/model/options/model.ckpt-4000000.pt +0 -0
  31. {ion_csp-2.0.4 → ion_csp-2.0.8}/param/INCAR_0 +0 -0
  32. {ion_csp-2.0.4 → ion_csp-2.0.8}/param/INCAR_1 +0 -0
  33. {ion_csp-2.0.4 → ion_csp-2.0.8}/param/INCAR_2 +0 -0
  34. {ion_csp-2.0.4 → ion_csp-2.0.8}/param/POTCAR_C +0 -0
  35. {ion_csp-2.0.4 → ion_csp-2.0.8}/param/POTCAR_H +0 -0
  36. {ion_csp-2.0.4 → ion_csp-2.0.8}/param/POTCAR_N +0 -0
  37. {ion_csp-2.0.4 → ion_csp-2.0.8}/param/POTCAR_O +0 -0
  38. {ion_csp-2.0.4 → ion_csp-2.0.8}/param/g16_sub.sh +0 -0
  39. {ion_csp-2.0.4 → ion_csp-2.0.8}/param/sub.sh +0 -0
  40. {ion_csp-2.0.4 → ion_csp-2.0.8}/pyproject.toml +0 -0
  41. {ion_csp-2.0.4 → ion_csp-2.0.8}/requirements.txt +0 -0
  42. {ion_csp-2.0.4 → ion_csp-2.0.8}/scripts/main_CSP.sh +0 -0
  43. {ion_csp-2.0.4 → ion_csp-2.0.8}/scripts/main_EE.sh +0 -0
  44. {ion_csp-2.0.4 → ion_csp-2.0.8}/scripts/main_usage.py +0 -0
  45. {ion_csp-2.0.4 → ion_csp-2.0.8}/scripts/main_usage.sh +0 -0
  46. {ion_csp-2.0.4 → ion_csp-2.0.8}/setup.cfg +0 -0
  47. {ion_csp-2.0.4 → ion_csp-2.0.8}/setup.py +0 -0
  48. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/__init__.py +0 -0
  49. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/__main__.py +0 -0
  50. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/convert_SMILES.py +0 -0
  51. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/empirical_estimate.py +0 -0
  52. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/gen_opt.py +0 -0
  53. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/identify_molecules.py +0 -0
  54. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/log_and_time.py +0 -0
  55. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/mlp_opt.py +0 -0
  56. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/steps_opt_monitor.sh +0 -0
  57. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/upload_download.py +0 -0
  58. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP/vasp_processing.py +0 -0
  59. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP.egg-info/SOURCES.txt +0 -0
  60. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP.egg-info/dependency_links.txt +0 -0
  61. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP.egg-info/entry_points.txt +0 -0
  62. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP.egg-info/requires.txt +0 -0
  63. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/ion_CSP.egg-info/top_level.txt +0 -0
  64. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/main_CSP.py +0 -0
  65. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/main_EE.py +0 -0
  66. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/run_convert_SMILES.py +0 -0
  67. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/run_empirical_estimate.py +0 -0
  68. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/run_gen_opt.py +0 -0
  69. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/run_read_mlp_density.py +0 -0
  70. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/run_upload_download.py +0 -0
  71. {ion_csp-2.0.4 → ion_csp-2.0.8}/src/run_vasp_processing.py +0 -0
  72. {ion_csp-2.0.4 → ion_csp-2.0.8}/tests/__init__.py +0 -0
  73. {ion_csp-2.0.4 → ion_csp-2.0.8}/tests/test1_task_manager1.py +0 -0
  74. {ion_csp-2.0.4 → ion_csp-2.0.8}/tests/test_task_manager.py +0 -0
  75. {ion_csp-2.0.4 → ion_csp-2.0.8}/uv.lock +0 -0
@@ -21,14 +21,13 @@ jobs:
21
21
  - name: Create environment
22
22
  run: |
23
23
  conda env create -f environment.yml --name ion-csp-env
24
- conda init bash
25
- conda activate ion-csp-env
26
24
 
27
25
  - name: Install dependencies
28
26
  run: |
29
- pip install -r requirements.txt
30
- pip install setuptools-scm
27
+ conda run --name ion-csp-env pip install -r requirements.txt
28
+ conda run --name ion-csp-env pip install setuptools-scm
29
+ conda run --name ion-csp-env pip install build
31
30
 
32
31
  - name: Build package
33
32
  run: |
34
- python -m build
33
+ conda run --name ion-csp-env python -m build
@@ -0,0 +1,47 @@
1
+ name: Python Package using Conda
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build-linux:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ max-parallel: 5
10
+
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - name: Set up Python 3.11
14
+ uses: actions/setup-python@v3
15
+ with:
16
+ python-version: '3.11'
17
+
18
+ - name: Set up conda
19
+ uses: conda-incubator/setup-miniconda@v3
20
+ with:
21
+ auto-activate-base: false
22
+ channels: conda-forge,defaults
23
+
24
+ - name: Create environment
25
+ run: |
26
+ conda env create -f environment.yml --name ion-csp-env
27
+
28
+ - name: Install dependencies
29
+ run: |
30
+ conda run --name ion-csp-env pip install -r requirements.txt
31
+ conda run --name ion-csp-env pip install setuptools-scm
32
+ conda run --name ion-csp-env pip install build
33
+
34
+ - name: Build package
35
+ run: |
36
+ conda run --name ion-csp-env python -m build
37
+
38
+ - name: Lint with flake8
39
+ run: |
40
+ conda run --name ion-csp-env conda install -y flake8
41
+ flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
42
+ flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
43
+
44
+ - name: Test with pytest
45
+ run: |
46
+ conda run --name ion-csp-env conda install -y pytest
47
+ pytest
@@ -27,6 +27,9 @@ jobs:
27
27
  python-version: "3.11"
28
28
 
29
29
  - name: Build release distributions
30
+ env:
31
+ TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
32
+ TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
30
33
  run: |
31
34
  # NOTE: put your own distribution build steps here.
32
35
  python -m pip install build
@@ -33,3 +33,6 @@ server_config
33
33
  *.yaml
34
34
  model_ori.pt
35
35
  logs/*
36
+ dist/*
37
+ *.tar.gz
38
+ *.whl
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ion_CSP
3
- Version: 2.0.4
3
+ Version: 2.0.8
4
4
  Summary: Crystal Structure Design Software Based on Molecular/Ionic Configuration.
5
5
  Home-page: https://github.com/bagabaga007/ion_CSP
6
6
  Author: Ze Yang
@@ -67,7 +67,7 @@ Dynamic: requires-python
67
67
  | paramiko | 3.5.1 |
68
68
  | pyxtal | 1.0.4 |
69
69
  | phonopy | 2.28.0 |
70
- | rdkit | 2023.03.3|
70
+ | rdkit | 2024.03.3|
71
71
 
72
72
  ### 安装步骤
73
73
  ```bash
@@ -172,7 +172,7 @@ This software enables efficient crystal structure screening from molecular/ion c
172
172
  | paramiko | 3.5.1 |
173
173
  | pyxtal | 1.0.4 |
174
174
  | phonopy | 2.28.0 |
175
- | rdkit | 2023.03.3|
175
+ | rdkit | 2024.03.3|
176
176
 
177
177
  ### Installation Steps
178
178
  ```bash
@@ -38,7 +38,7 @@
38
38
  | paramiko | 3.5.1 |
39
39
  | pyxtal | 1.0.4 |
40
40
  | phonopy | 2.28.0 |
41
- | rdkit | 2023.03.3|
41
+ | rdkit | 2024.03.3|
42
42
 
43
43
  ### 安装步骤
44
44
  ```bash
@@ -143,7 +143,7 @@ This software enables efficient crystal structure screening from molecular/ion c
143
143
  | paramiko | 3.5.1 |
144
144
  | pyxtal | 1.0.4 |
145
145
  | phonopy | 2.28.0 |
146
- | rdkit | 2023.03.3|
146
+ | rdkit | 2024.03.3|
147
147
 
148
148
  ### Installation Steps
149
149
  ```bash
@@ -1,8 +1,8 @@
1
1
  __author__ = "Ze Yang"
2
2
  __contact__ = "yangze1995007@163.com"
3
3
  __license__ = "MIT"
4
- __version__ = "2.0.4"
5
- __date__ = "2025-04-24"
4
+ __version__ = "2.0.8"
5
+ __date__ = "2025-05-14"
6
6
 
7
7
 
8
8
  try:
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import csv
2
3
  import shutil
3
4
  import logging
4
5
  import subprocess
@@ -76,15 +77,30 @@ class ReadMlpDensity:
76
77
  os.makedirs(backup_dir, exist_ok=True)
77
78
  for item in os.listdir(self.max_density_dir):
78
79
  shutil.move(os.path.join(self.max_density_dir, item), os.path.join(backup_dir, item))
79
-
80
+ numbers, mlp_densities, mlp_energies = [], [], []
80
81
  os.makedirs(self.max_density_dir, exist_ok=True)
81
82
  for density, CONTCAR_filename in sorted_filename[:n_screen]:
82
83
  # 生成新的包含密度值的文件名,并重命名文件
83
84
  # 密度转换为字符串,保留4位小数
84
85
  density_str = f'{density:.4f}'
86
+ mlp_densities.append(density_str)
85
87
  # 保留 CONTCAR 的序数信息,方便回推检查
86
88
  number = CONTCAR_filename.split("_")[1]
89
+ numbers.append(number)
87
90
  OUTCAR_filename = f'OUTCAR_{number}'
91
+ try:
92
+ with open(f"{self.folder_dir}/OUTCAR_{number}") as mlp_out:
93
+ lines = mlp_out.readlines()
94
+ for line in lines:
95
+ if "TOTEN" in line:
96
+ values = line.split()
97
+ mlp_energy = round(float(values[-2]), 2)
98
+ except FileNotFoundError:
99
+ logging.error(
100
+ f" No avalible MLP OUTCAR_{number} found"
101
+ )
102
+ mlp_energy = False
103
+ mlp_energies.append(mlp_energy)
88
104
  new_CONTCAR_filename = f'CONTCAR_{density_str}_{number}'
89
105
  new_OUTCAR_filename = f'OUTCAR_{density_str}_{number}'
90
106
  shutil.copy(f'{self.folder_dir}/{CONTCAR_filename}', f'{self.max_density_dir}/{new_CONTCAR_filename}')
@@ -92,6 +108,30 @@ class ReadMlpDensity:
92
108
  print(f'New CONTCAR and OUTCAR of {density_str}_{number} are renamed and saved')
93
109
  logging.info(f'New CONTCAR and OUTCAR of {density_str}_{number} are renamed and saved')
94
110
 
111
+ with open(
112
+ f"{self.max_density_dir}/mlp_density_energy.csv",
113
+ "w",
114
+ newline="",
115
+ encoding="utf-8",
116
+ ) as csv_file:
117
+ writer = csv.writer(csv_file)
118
+ header = [
119
+ "Number",
120
+ "MLP_E",
121
+ "MLP_Density",
122
+ ]
123
+ datas = list(
124
+ zip(
125
+ numbers,
126
+ mlp_energies,
127
+ mlp_densities,
128
+ )
129
+ )
130
+ datas.sort(key=lambda x: -float(x[-1]))
131
+ writer.writerow(header)
132
+ for data in datas:
133
+ writer.writerow(data)
134
+
95
135
  def phonopy_processing_max_density(self, specific_directory :str = None):
96
136
  """
97
137
  Use phonopy to check and generate symmetric primitive cells, reducing the complexity of subsequent optimization calculations, and preventing pyxtal.from_random from generating double proportioned supercells.
@@ -127,14 +167,18 @@ class ReadMlpDensity:
127
167
  # 复制对应的OUTCAR文件到primitive_cell目录下
128
168
  density_number = new_CONTCAR_filename.split("CONTCAR_")[1]
129
169
  new_OUTCAR_filename = f'OUTCAR_{density_number}'
130
- shutil.copy(f'{self.max_density_dir}/{new_OUTCAR_filename}', f'{self.primitive_cell_dir}/{new_OUTCAR_filename}')
170
+ shutil.copy(f'{self.phonopy_dir}/{new_OUTCAR_filename}', f'{self.primitive_cell_dir}/{new_OUTCAR_filename}')
171
+ shutil.copy(
172
+ f"{self.phonopy_dir}/mlp_density_energy.csv",
173
+ f"{self.primitive_cell_dir}/mlp_density_energy.csv",
174
+ )
131
175
  for_vasp_opt_dir = os.path.join(self.base_dir, '3_for_vasp_opt')
132
176
  if os.path.exists(for_vasp_opt_dir):
133
177
  shutil.rmtree(for_vasp_opt_dir)
134
178
  shutil.copytree(self.primitive_cell_dir, for_vasp_opt_dir)
135
179
  logging.info('The phonopy processing has been completed!!\nThe symmetrized primitive cells have been saved in POSCAR format to the primitive_cell folder.\nThe output content of phonopy has been saved to the phonopy.log file in the same directory.')
136
180
  # 在 phonopy 成功进行对称化处理后,删除 2_mlp_optimized/max_density 文件夹以节省空间
137
- shutil.rmtree(self.max_density_dir)
181
+ shutil.rmtree(self.phonopy_dir)
138
182
  except FileNotFoundError:
139
183
  logging.error(
140
184
  "There are no CONTCAR structure files after screening.\nPlease check if the ions correspond to the crystals and adjust the screening criteria"
@@ -125,7 +125,7 @@ class TaskManager:
125
125
  def _display_tasks(self, tasks, total, current_page, total_pages, function):
126
126
  """标准化任务显示 - Standardized tasks display"""
127
127
  display = "logs" if function == "view" else "tasks"
128
- print(f"\033cPage {current_page}/{total_pages} ({total} {display})")
128
+ print(f"\033cPage {current_page}/{total_pages} ({total} {display})\n")
129
129
  if function == "kill":
130
130
  for i, task in enumerate(tasks, 1):
131
131
  print(
@@ -138,11 +138,11 @@ class TaskManager:
138
138
  )
139
139
  else:
140
140
  raise ValueError(f"Not supported function {function}. Available function: 'view' and 'kill' ")
141
- print("\nPage {} of {}".format(current_page, total_pages))
142
141
  # 分页控制
143
142
  print("\nOptions:")
144
143
  if function == "view":
145
144
  print("n) Next page | p) Previous page | f) Filter | q) Quit")
145
+ print("Enter number to view log in detail")
146
146
  elif function == "kill":
147
147
  print("n) Next page | p) Previous page | f) Filter | k) Kill | q) Quit")
148
148
  else:
@@ -171,10 +171,11 @@ class TaskManager:
171
171
  elif function == "kill" and choice == "K":
172
172
  try:
173
173
  task_num = input("Enter task number to kill: ").strip()
174
- if not task_num.isdigit():
174
+ if task_num.isdigit() and 1 <= int(task_num) <= 10:
175
+ # 计算全局任务索引
176
+ global_index = current_page * 10 + (int(task_num) - 1)
177
+ else:
175
178
  raise ValueError
176
- # 计算全局任务索引
177
- global_index = current_page * 10 + (int(task_num) - 1)
178
179
  if 0 <= global_index < len(tasks):
179
180
  selected_index = global_index
180
181
  confirm = input(
@@ -189,10 +190,10 @@ class TaskManager:
189
190
  else:
190
191
  print("Invalid task number")
191
192
  input("\nPress Enter to continue...")
192
- except ValueError:
193
+ except (ValueError, TypeError):
193
194
  print("Please enter a valid number")
194
195
  input("\nPress Enter to continue...")
195
- elif function == "view" and choice.isdigit():
196
+ elif function == "view" and choice.isdigit() and 1<= int(choice) <=10:
196
197
  # 计算全局任务索引
197
198
  global_index = current_page * 10 + (int(choice) - 1)
198
199
  if 0 <= global_index < len(tasks):
@@ -255,6 +256,8 @@ class TaskManager:
255
256
  os.remove(std_log)
256
257
  std_log.symlink_to(output_log)
257
258
 
259
+ print('Starting task ......')
260
+ time.sleep(6)
258
261
  logging.info(f"Started {module} module (PID: {process.pid})")
259
262
  print(f"Task started (PID: {process.pid})")
260
263
  print(f"Normalized log file: {std_log}")
@@ -366,7 +369,7 @@ class TaskManager:
366
369
  print("q) Exit")
367
370
  print("=" * 50)
368
371
 
369
- choice = input("Please enter operation: ").strip().lower()
372
+ choice = input("Please select an operation: ").strip().lower()
370
373
  if choice == "1":
371
374
  work_dir = input("Enter EE working directory: ").strip()
372
375
  self.task_runner("EE", work_dir)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ion_CSP
3
- Version: 2.0.4
3
+ Version: 2.0.8
4
4
  Summary: Crystal Structure Design Software Based on Molecular/Ionic Configuration.
5
5
  Home-page: https://github.com/bagabaga007/ion_CSP
6
6
  Author: Ze Yang
@@ -67,7 +67,7 @@ Dynamic: requires-python
67
67
  | paramiko | 3.5.1 |
68
68
  | pyxtal | 1.0.4 |
69
69
  | phonopy | 2.28.0 |
70
- | rdkit | 2023.03.3|
70
+ | rdkit | 2024.03.3|
71
71
 
72
72
  ### 安装步骤
73
73
  ```bash
@@ -172,7 +172,7 @@ This software enables efficient crystal structure screening from molecular/ion c
172
172
  | paramiko | 3.5.1 |
173
173
  | pyxtal | 1.0.4 |
174
174
  | phonopy | 2.28.0 |
175
- | rdkit | 2023.03.3|
175
+ | rdkit | 2024.03.3|
176
176
 
177
177
  ### Installation Steps
178
178
  ```bash
@@ -1,43 +0,0 @@
1
- name: Python Package using Conda
2
-
3
- on: [push]
4
-
5
- jobs:
6
- build-linux:
7
- runs-on: ubuntu-latest
8
- strategy:
9
- max-parallel: 5
10
-
11
- steps:
12
- - uses: actions/checkout@v4
13
- - name: Set up Python 3.11
14
- uses: actions/setup-python@v3
15
- with:
16
- python-version: '3.11'
17
- - name: Add conda to system path
18
- run: |
19
- # $CONDA is an environment variable pointing to the root of the miniconda directory
20
- echo $CONDA/bin >> $GITHUB_PATH
21
- - name: Install dependencies
22
- run: |
23
- conda env update --file environment.yml --name ion-csp-env
24
- conda init
25
- conda activate ion-csp-env
26
- - name: Install dependencies
27
- run: |
28
- pip install -r requirements.txt
29
- pip install setuptools-scm
30
- - name: Build package
31
- run: |
32
- python -m build
33
- - name: Lint with flake8
34
- run: |
35
- conda install flake8
36
- # stop the build if there are Python syntax errors or undefined names
37
- flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
38
- # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
39
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
40
- - name: Test with pytest
41
- run: |
42
- conda install pytest
43
- pytest
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes