23 |
45 |
46 |
47 | See [Getting started](getting_started.md) for a quick tutorial on how to use the library.
48 |
49 | See [Inspiration](inspiration.md) for a more in-depth explanation of the motivation behind this project.
50 |
51 |
33 |
84 |
85 | ### Pretty neat, right?
86 |
87 |
88 | ## 🚀 Installation
89 |
90 | ```bash
91 | pip install python-hooks
92 | ```
93 |
94 | ## 🎯 What's next
95 |
96 | Well, that's up to you 💪🏻. We are looking for contributors to help us build this project and make it better. If you are interested in contributing, please reach out to me on [Discord](https://discord.gg/mayParnv) or open an issue.
97 | In addition we are looking for plugin developers to help us build more plugins for different state stores.
98 |
99 | ## 📈 Releases
100 |
101 | You can see the list of available releases on the [GitHub Releases](https://github.com/amitassaraf/python-hooks/releases) page.
102 |
103 | We follow [Semantic Versions](https://semver.org/) specification.
104 |
105 | We use [`Release Drafter`](https://github.com/marketplace/actions/release-drafter). As pull requests are merged, a draft release is kept up-to-date listing the changes, ready to publish when you’re ready. With the categories option, you can categorize pull requests in release notes using labels.
106 |
107 | ### List of labels and corresponding titles
108 |
109 | | **Label** | **Title in Releases** |
110 | | :-----------------------------------: | :---------------------: |
111 | | `enhancement`, `feature` | 🚀 Features |
112 | | `bug`, `refactoring`, `bugfix`, `fix` | 🔧 Fixes & Refactoring |
113 | | `build`, `ci`, `testing` | 📦 Build System & CI/CD |
114 | | `breaking` | 💥 Breaking Changes |
115 | | `documentation` | 📝 Documentation |
116 | | `dependencies` | ⬆️ Dependencies updates |
117 |
118 |
119 | GitHub creates the `bug`, `enhancement`, and `documentation` labels for you. Dependabot creates the `dependencies` label. Create the remaining labels on the Issues tab of your GitHub repository, when you need them.
120 |
121 |
122 | ## 📋 Roadmap
123 |
124 | - [x] Finish documentation
125 | - [x] Improve frame identifier without hurting performance
126 | - [x] Add redux plugin
127 | - [x] Async support ⚡
128 | - [ ] Handle code versioning (Moving state around the code) [!]
129 | - [ ] Develop state-debugger plugin
130 | - [ ] Test and adapt to PyPy, Jython, IronPython
131 | - [ ] Support for more hook backends
132 | - [ ] MongoDB
133 | - [ ] Postgres
134 | - [ ] MySQL
135 | - [ ] SQLite
136 |
137 | See the [open issues](https://github.com/amitassaraf/python-hooks/issues) for a full list of proposed features (and known issues).
138 |
139 | ## 🛡 License
140 |
141 | [](https://github.com/amitassaraf/python-hooks/blob/master/LICENSE)
142 |
143 | This project is licensed under the terms of the `MIT` license. See [LICENSE](https://github.com/amitassaraf/python-hooks/blob/master/LICENSE) for more details.
144 |
145 | ## 📃 Citation
146 |
147 | ```bibtex
148 | @misc{python-hooks,
149 | author = {Amit Assaraf},
150 | title = {A React inspired way to code in Python},
151 | year = {2023},
152 | publisher = {GitHub},
153 | journal = {GitHub repository},
154 | howpublished = {\url{https://github.com/amitassaraf/python-hooks}}
155 | }
156 | ```
157 |
--------------------------------------------------------------------------------
/tests/test_hooks/test_hook_scope.py:
--------------------------------------------------------------------------------
1 | from hooks.asyncio.use import use_state as async_use_state
2 | from hooks.scope import hook_scope
3 | from hooks.use import use_state
4 |
5 |
6 | def test_local_state() -> None:
7 | class Foo:
8 | @hook_scope(parametrize=["counter_name"])
9 | def local_state(self, counter_name: str) -> int:
10 | counter, set_counter = use_state(0)
11 | set_counter(counter + 1)
12 | return counter
13 |
14 | foo = Foo()
15 |
16 | assert foo.local_state("A") == 0
17 | assert foo.local_state("A") == 1
18 | assert foo.local_state("B") == 0
19 | assert foo.local_state("B") == 1
20 | assert foo.local_state("A") == 2
21 | assert Foo().local_state("A") == 0
22 | assert Foo().local_state("A") == 0
23 |
24 |
25 | def test_global_state() -> None:
26 | class Foo:
27 | @staticmethod
28 | @hook_scope()
29 | def global_state(counter_name: str) -> int:
30 | counter, set_counter = use_state(0)
31 | set_counter(counter + 1)
32 | return counter
33 |
34 | foo = Foo()
35 |
36 | assert Foo.global_state("A") == 0
37 | assert foo.global_state("A") == 1
38 | assert Foo().global_state("A") == 2
39 | assert Foo().global_state("B") == 0
40 | assert Foo().global_state("B") == 1
41 |
42 |
43 | def test_global_state_without_arguments() -> None:
44 | @hook_scope()
45 | def global_state() -> int:
46 | counter, set_counter = use_state(0)
47 | set_counter(counter + 1)
48 | return counter
49 |
50 | assert global_state() == 0
51 | assert global_state() == 1
52 |
53 |
54 | def test_class_state() -> None:
55 | class Bar:
56 | @classmethod
57 | @hook_scope(parametrize=["counter_name"])
58 | def class_state(cls, counter_name: str) -> int:
59 | counter, set_counter = use_state(0)
60 | set_counter(counter + 1)
61 | return counter
62 |
63 | bar = Bar()
64 | assert Bar.class_state("A") == 0
65 | assert Bar.class_state("A") == 1
66 | assert bar.class_state("A") == 2
67 | assert bar.class_state("B") == 0
68 | assert bar.class_state("B") == 1
69 |
70 |
71 | def test_hook_scope_of_nested_functions() -> None:
72 | class Foo:
73 | def nested_state(self) -> int:
74 | counter, set_counter = use_state(0)
75 | set_counter(counter + 1)
76 | return counter
77 |
78 | @hook_scope(parametrize=["counter_name"])
79 | def local_state(self, counter_name: str) -> int:
80 | return self.nested_state()
81 |
82 | foo = Foo()
83 |
84 | assert foo.local_state("A") == 0
85 | assert foo.local_state("A") == 1
86 | assert foo.local_state("B") == 0
87 | assert foo.local_state("B") == 1
88 | assert foo.local_state("A") == 2
89 | assert Foo().local_state("A") == 0
90 | assert Foo().local_state("A") == 0
91 |
92 |
93 | def test_nested_hook_scopes() -> None:
94 | class Foo:
95 | @hook_scope()
96 | def nested_state_with_scope(self) -> int:
97 | counter, set_counter = use_state(0)
98 | set_counter(counter + 1)
99 | return counter
100 |
101 | @hook_scope(parametrize=["counter_name"])
102 | def local_state(self, counter_name: str) -> int:
103 | return self.nested_state_with_scope()
104 |
105 | foo = Foo()
106 |
107 | assert foo.local_state("A") == 0
108 | assert foo.local_state("A") == 1
109 | assert foo.local_state("B") == 0
110 | assert foo.local_state("B") == 1
111 | assert foo.local_state("A") == 2
112 | assert Foo().local_state("A") == 0
113 | assert Foo().local_state("A") == 0
114 |
115 |
116 | def test_local_state_that_is_scoped_globally() -> None:
117 | class Foo:
118 | @hook_scope(use_global_scope=True, parametrize=[])
119 | def local_state(self) -> int:
120 | counter, set_counter = use_state(0)
121 | set_counter(counter + 1)
122 | return counter
123 |
124 | foo = Foo()
125 |
126 | assert foo.local_state() == 0
127 | assert foo.local_state() == 1
128 | assert Foo().local_state() == 2
129 | assert Foo().local_state() == 3
130 |
131 |
132 | ########################################################################################################################
133 | # Asynchronous
134 | ########################################################################################################################
135 |
136 |
137 | async def test_local_state_async(async_backend) -> None:
138 | class Foo:
139 | @hook_scope(parametrize=["counter_name"])
140 | async def local_state(self, counter_name: str) -> int:
141 | counter, set_counter = await async_use_state(0)
142 | await set_counter(counter + 1)
143 | return counter
144 |
145 | foo = Foo()
146 |
147 | assert await foo.local_state("A") == 0
148 | assert await foo.local_state("A") == 1
149 | assert await foo.local_state("B") == 0
150 | assert await foo.local_state("B") == 1
151 | assert await foo.local_state("A") == 2
152 | assert await Foo().local_state("A") == 0
153 | assert await Foo().local_state("A") == 0
154 |
155 |
156 | async def test_global_state_async(async_backend) -> None:
157 | class Foo:
158 | @staticmethod
159 | @hook_scope()
160 | async def global_state(counter_name: str) -> int:
161 | counter, set_counter = await async_use_state(0)
162 | await set_counter(counter + 1)
163 | return counter
164 |
165 | foo = Foo()
166 |
167 | assert await Foo.global_state("A") == 0
168 | assert await foo.global_state("A") == 1
169 | assert await Foo().global_state("A") == 2
170 | assert await Foo().global_state("B") == 0
171 | assert await Foo().global_state("B") == 1
172 |
173 |
174 | async def test_global_state_without_arguments_async(async_backend) -> None:
175 | @hook_scope()
176 | async def global_state() -> int:
177 | counter, set_counter = await async_use_state(0)
178 | await set_counter(counter + 1)
179 | return counter
180 |
181 | assert await global_state() == 0
182 | assert await global_state() == 1
183 |
184 |
185 | async def test_class_state_async(async_backend) -> None:
186 | class Bar:
187 | @classmethod
188 | @hook_scope(parametrize=["counter_name"])
189 | async def class_state(cls, counter_name: str) -> int:
190 | counter, set_counter = await async_use_state(0)
191 | await set_counter(counter + 1)
192 | return counter
193 |
194 | bar = Bar()
195 | assert await Bar.class_state("A") == 0
196 | assert await Bar.class_state("A") == 1
197 | assert await bar.class_state("A") == 2
198 | assert await bar.class_state("B") == 0
199 | assert await bar.class_state("B") == 1
200 |
201 |
202 | async def test_hook_scope_of_nested_functions_async(async_backend) -> None:
203 | class Foo:
204 | async def nested_state(self) -> int:
205 | counter, set_counter = await async_use_state(0)
206 | await set_counter(counter + 1)
207 | return counter
208 |
209 | @hook_scope(parametrize=["counter_name"])
210 | async def local_state(self, counter_name: str) -> int:
211 | return await self.nested_state()
212 |
213 | foo = Foo()
214 |
215 | assert await foo.local_state("A") == 0
216 | assert await foo.local_state("A") == 1
217 | assert await foo.local_state("B") == 0
218 | assert await foo.local_state("B") == 1
219 | assert await foo.local_state("A") == 2
220 | assert await Foo().local_state("A") == 0
221 | assert await Foo().local_state("A") == 0
222 |
223 |
224 | async def test_nested_hook_scopes_async(async_backend) -> None:
225 | class Foo:
226 | @hook_scope()
227 | async def nested_state_with_scope(self) -> int:
228 | counter, set_counter = await async_use_state(0)
229 | await set_counter(counter + 1)
230 | return counter
231 |
232 | @hook_scope(parametrize=["counter_name"])
233 | async def local_state(self, counter_name: str) -> int:
234 | return await self.nested_state_with_scope()
235 |
236 | foo = Foo()
237 |
238 | assert await foo.local_state("A") == 0
239 | assert await foo.local_state("A") == 1
240 | assert await foo.local_state("B") == 0
241 | assert await foo.local_state("B") == 1
242 | assert await foo.local_state("A") == 2
243 | assert await Foo().local_state("A") == 0
244 | assert await Foo().local_state("A") == 0
245 |
246 |
247 | async def test_local_state_that_is_scoped_globally_async(async_backend) -> None:
248 | class Foo:
249 | @hook_scope(use_global_scope=True, parametrize=[])
250 | async def local_state(self) -> int:
251 | counter, set_counter = await async_use_state(0)
252 | await set_counter(counter + 1)
253 | return counter
254 |
255 | foo = Foo()
256 |
257 | assert await foo.local_state() == 0
258 | assert await foo.local_state() == 1
259 | assert await Foo().local_state() == 2
260 | assert await Foo().local_state() == 3
261 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/osx,python,pycharm,windows,visualstudio,visualstudiocode
3 | # Edit at https://www.gitignore.io/?templates=osx,python,pycharm,windows,visualstudio,visualstudiocode
4 |
5 | ### OSX ###
6 | # General
7 | .DS_Store
8 | .AppleDouble
9 | .LSOverride
10 |
11 | # Icon must end with two \r
12 | Icon
13 |
14 | # Thumbnails
15 | ._*
16 |
17 | # Files that might appear in the root of a volume
18 | .DocumentRevisions-V100
19 | .fseventsd
20 | .Spotlight-V100
21 | .TemporaryItems
22 | .Trashes
23 | .VolumeIcon.icns
24 | .com.apple.timemachine.donotpresent
25 |
26 | # Directories potentially created on remote AFP share
27 | .AppleDB
28 | .AppleDesktop
29 | Network Trash Folder
30 | Temporary Items
31 | .apdisk
32 |
33 | ### PyCharm ###
34 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
35 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
36 |
37 | # User-specific stuff
38 | .idea/**/workspace.xml
39 | .idea/**/tasks.xml
40 | .idea/**/usage.statistics.xml
41 | .idea/**/dictionaries
42 | .idea/**/shelf
43 |
44 | # Generated files
45 | .idea/**/contentModel.xml
46 |
47 | # Sensitive or high-churn files
48 | .idea/**/dataSources/
49 | .idea/**/dataSources.ids
50 | .idea/**/dataSources.local.xml
51 | .idea/**/sqlDataSources.xml
52 | .idea/**/dynamic.xml
53 | .idea/**/uiDesigner.xml
54 | .idea/**/dbnavigator.xml
55 |
56 | # Gradle
57 | .idea/**/gradle.xml
58 | .idea/**/libraries
59 |
60 | # Gradle and Maven with auto-import
61 | # When using Gradle or Maven with auto-import, you should exclude module files,
62 | # since they will be recreated, and may cause churn. Uncomment if using
63 | # auto-import.
64 | # .idea/modules.xml
65 | # .idea/*.iml
66 | # .idea/modules
67 | # *.iml
68 | # *.ipr
69 |
70 | # CMake
71 | cmake-build-*/
72 |
73 | # Mongo Explorer plugin
74 | .idea/**/mongoSettings.xml
75 |
76 | # File-based project format
77 | *.iws
78 |
79 | # IntelliJ
80 | out/
81 |
82 | # mpeltonen/sbt-idea plugin
83 | .idea_modules/
84 |
85 | # JIRA plugin
86 | atlassian-ide-plugin.xml
87 |
88 | # Cursive Clojure plugin
89 | .idea/replstate.xml
90 |
91 | # Crashlytics plugin (for Android Studio and IntelliJ)
92 | com_crashlytics_export_strings.xml
93 | crashlytics.properties
94 | crashlytics-build.properties
95 | fabric.properties
96 |
97 | # Editor-based Rest Client
98 | .idea/httpRequests
99 |
100 | # Android studio 3.1+ serialized cache file
101 | .idea/caches/build_file_checksums.ser
102 |
103 | ### PyCharm Patch ###
104 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
105 |
106 | # *.iml
107 | # modules.xml
108 | # .idea/misc.xml
109 | # *.ipr
110 |
111 | # Sonarlint plugin
112 | .idea/**/sonarlint/
113 |
114 | # SonarQube Plugin
115 | .idea/**/sonarIssues.xml
116 |
117 | # Markdown Navigator plugin
118 | .idea/**/markdown-navigator.xml
119 | .idea/**/markdown-navigator/
120 |
121 | ### Python ###
122 | # Byte-compiled / optimized / DLL files
123 | __pycache__/
124 | *.py[cod]
125 | *$py.class
126 |
127 | # C extensions
128 | *.so
129 |
130 | # Distribution / packaging
131 | .Python
132 | build/
133 | develop-eggs/
134 | dist/
135 | downloads/
136 | eggs/
137 | .eggs/
138 | lib/
139 | lib64/
140 | parts/
141 | sdist/
142 | var/
143 | wheels/
144 | pip-wheel-metadata/
145 | share/python-wheels/
146 | *.egg-info/
147 | .installed.cfg
148 | *.egg
149 | MANIFEST
150 |
151 | # PyInstaller
152 | # Usually these files are written by a python script from a template
153 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
154 | *.manifest
155 | *.spec
156 |
157 | # Installer logs
158 | pip-log.txt
159 | pip-delete-this-directory.txt
160 |
161 | # Unit test / coverage reports
162 | htmlcov/
163 | .tox/
164 | .nox/
165 | .coverage
166 | .coverage.*
167 | .cache
168 | nosetests.xml
169 | coverage.xml
170 | *.cover
171 | .hypothesis/
172 | .pytest_cache/
173 |
174 | # Translations
175 | *.mo
176 | *.pot
177 |
178 | # Scrapy stuff:
179 | .scrapy
180 |
181 | # Sphinx documentation
182 | docs/_build/
183 |
184 | # PyBuilder
185 | target/
186 |
187 | # pyenv
188 | .python-version
189 |
190 | # poetry
191 | .venv
192 |
193 | # pipenv
194 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
195 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
196 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
197 | # install all needed dependencies.
198 | #Pipfile.lock
199 |
200 | # celery beat schedule file
201 | celerybeat-schedule
202 |
203 | # SageMath parsed files
204 | *.sage.py
205 |
206 | # Spyder project settings
207 | .spyderproject
208 | .spyproject
209 |
210 | # Rope project settings
211 | .ropeproject
212 |
213 | # Mr Developer
214 | .mr.developer.cfg
215 | .project
216 | .pydevproject
217 |
218 | # mkdocs documentation
219 | /site
220 |
221 | # mypy
222 | .mypy_cache/
223 | .dmypy.json
224 | dmypy.json
225 |
226 | # Pyre type checker
227 | .pyre/
228 |
229 | # Plugins
230 | .secrets.baseline
231 |
232 | ### VisualStudioCode ###
233 | .vscode/*
234 | !.vscode/tasks.json
235 | !.vscode/launch.json
236 | !.vscode/extensions.json
237 |
238 | ### VisualStudioCode Patch ###
239 | # Ignore all local history of files
240 | .history
241 |
242 | ### Windows ###
243 | # Windows thumbnail cache files
244 | Thumbs.db
245 | Thumbs.db:encryptable
246 | ehthumbs.db
247 | ehthumbs_vista.db
248 |
249 | # Dump file
250 | *.stackdump
251 |
252 | # Folder config file
253 | [Dd]esktop.ini
254 |
255 | # Recycle Bin used on file shares
256 | $RECYCLE.BIN/
257 |
258 | # Windows Installer files
259 | *.cab
260 | *.msi
261 | *.msix
262 | *.msm
263 | *.msp
264 |
265 | # Windows shortcuts
266 | *.lnk
267 |
268 | ### VisualStudio ###
269 | ## Ignore Visual Studio temporary files, build results, and
270 | ## files generated by popular Visual Studio add-ons.
271 | ##
272 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
273 |
274 | # User-specific files
275 | *.rsuser
276 | *.suo
277 | *.user
278 | *.userosscache
279 | *.sln.docstates
280 |
281 | # User-specific files (MonoDevelop/Xamarin Studio)
282 | *.userprefs
283 |
284 | # Mono auto generated files
285 | mono_crash.*
286 |
287 | # Build results
288 | [Dd]ebug/
289 | [Dd]ebugPublic/
290 | [Rr]elease/
291 | [Rr]eleases/
292 | x64/
293 | x86/
294 | [Aa][Rr][Mm]/
295 | [Aa][Rr][Mm]64/
296 | bld/
297 | [Bb]in/
298 | [Oo]bj/
299 | [Ll]og/
300 |
301 | # Visual Studio 2015/2017 cache/options directory
302 | .vs/
303 | # Uncomment if you have tasks that create the project's static files in wwwroot
304 | #wwwroot/
305 |
306 | # Visual Studio 2017 auto generated files
307 | Generated\ Files/
308 |
309 | # MSTest test Results
310 | [Tt]est[Rr]esult*/
311 | [Bb]uild[Ll]og.*
312 |
313 | # NUnit
314 | *.VisualState.xml
315 | TestResult.xml
316 | nunit-*.xml
317 |
318 | # Build Results of an ATL Project
319 | [Dd]ebugPS/
320 | [Rr]eleasePS/
321 | dlldata.c
322 |
323 | # Benchmark Results
324 | BenchmarkDotNet.Artifacts/
325 |
326 | # .NET Core
327 | project.lock.json
328 | project.fragment.lock.json
329 | artifacts/
330 |
331 | # StyleCop
332 | StyleCopReport.xml
333 |
334 | # Files built by Visual Studio
335 | *_i.c
336 | *_p.c
337 | *_h.h
338 | *.ilk
339 | *.obj
340 | *.iobj
341 | *.pch
342 | *.pdb
343 | *.ipdb
344 | *.pgc
345 | *.pgd
346 | *.rsp
347 | *.sbr
348 | *.tlb
349 | *.tli
350 | *.tlh
351 | *.tmp
352 | *.tmp_proj
353 | *_wpftmp.csproj
354 | *.log
355 | *.vspscc
356 | *.vssscc
357 | .builds
358 | *.pidb
359 | *.svclog
360 | *.scc
361 |
362 | # Chutzpah Test files
363 | _Chutzpah*
364 |
365 | # Visual C++ cache files
366 | ipch/
367 | *.aps
368 | *.ncb
369 | *.opendb
370 | *.opensdf
371 | *.sdf
372 | *.cachefile
373 | *.VC.db
374 | *.VC.VC.opendb
375 |
376 | # Visual Studio profiler
377 | *.psess
378 | *.vsp
379 | *.vspx
380 | *.sap
381 |
382 | # Visual Studio Trace Files
383 | *.e2e
384 |
385 | # TFS 2012 Local Workspace
386 | $tf/
387 |
388 | # Guidance Automation Toolkit
389 | *.gpState
390 |
391 | # ReSharper is a .NET coding add-in
392 | _ReSharper*/
393 | *.[Rr]e[Ss]harper
394 | *.DotSettings.user
395 |
396 | # JustCode is a .NET coding add-in
397 | .JustCode
398 |
399 | # TeamCity is a build add-in
400 | _TeamCity*
401 |
402 | # DotCover is a Code Coverage Tool
403 | *.dotCover
404 |
405 | # AxoCover is a Code Coverage Tool
406 | .axoCover/*
407 | !.axoCover/settings.json
408 |
409 | # Visual Studio code coverage results
410 | *.coverage
411 | *.coveragexml
412 |
413 | # NCrunch
414 | _NCrunch_*
415 | .*crunch*.local.xml
416 | nCrunchTemp_*
417 |
418 | # MightyMoose
419 | *.mm.*
420 | AutoTest.Net/
421 |
422 | # Web workbench (sass)
423 | .sass-cache/
424 |
425 | # Installshield output folder
426 | [Ee]xpress/
427 |
428 | # DocProject is a documentation generator add-in
429 | DocProject/buildhelp/
430 | DocProject/Help/*.HxT
431 | DocProject/Help/*.HxC
432 | DocProject/Help/*.hhc
433 | DocProject/Help/*.hhk
434 | DocProject/Help/*.hhp
435 | DocProject/Help/Html2
436 | DocProject/Help/html
437 |
438 | # Click-Once directory
439 | publish/
440 |
441 | # Publish Web Output
442 | *.[Pp]ublish.xml
443 | *.azurePubxml
444 | # Note: Comment the next line if you want to checkin your web deploy settings,
445 | # but database connection strings (with potential passwords) will be unencrypted
446 | *.pubxml
447 | *.publishproj
448 |
449 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
450 | # checkin your Azure Web App publish settings, but sensitive information contained
451 | # in these scripts will be unencrypted
452 | PublishScripts/
453 |
454 | # NuGet Packages
455 | *.nupkg
456 | # NuGet Symbol Packages
457 | *.snupkg
458 | # The packages folder can be ignored because of Package Restore
459 | **/[Pp]ackages/*
460 | # except build/, which is used as an MSBuild target.
461 | !**/[Pp]ackages/build/
462 | # Uncomment if necessary however generally it will be regenerated when needed
463 | #!**/[Pp]ackages/repositories.config
464 | # NuGet v3's project.json files produces more ignorable files
465 | *.nuget.props
466 | *.nuget.targets
467 |
468 | # Microsoft Azure Build Output
469 | csx/
470 | *.build.csdef
471 |
472 | # Microsoft Azure Emulator
473 | ecf/
474 | rcf/
475 |
476 | # Windows Store app package directories and files
477 | AppPackages/
478 | BundleArtifacts/
479 | Package.StoreAssociation.xml
480 | _pkginfo.txt
481 | *.appx
482 | *.appxbundle
483 | *.appxupload
484 |
485 | # Visual Studio cache files
486 | # files ending in .cache can be ignored
487 | *.[Cc]ache
488 | # but keep track of directories ending in .cache
489 | !?*.[Cc]ache/
490 |
491 | # Others
492 | ClientBin/
493 | ~$*
494 | *~
495 | *.dbmdl
496 | *.dbproj.schemaview
497 | *.jfm
498 | *.pfx
499 | *.publishsettings
500 | orleans.codegen.cs
501 |
502 | # Including strong name files can present a security risk
503 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
504 | #*.snk
505 |
506 | # Since there are multiple workflows, uncomment next line to ignore bower_components
507 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
508 | #bower_components/
509 |
510 | # RIA/Silverlight projects
511 | Generated_Code/
512 |
513 | # Backup & report files from converting an old project file
514 | # to a newer Visual Studio version. Backup files are not needed,
515 | # because we have git ;-)
516 | _UpgradeReport_Files/
517 | Backup*/
518 | UpgradeLog*.XML
519 | UpgradeLog*.htm
520 | ServiceFabricBackup/
521 | *.rptproj.bak
522 |
523 | # SQL Server files
524 | *.mdf
525 | *.ldf
526 | *.ndf
527 |
528 | # Business Intelligence projects
529 | *.rdl.data
530 | *.bim.layout
531 | *.bim_*.settings
532 | *.rptproj.rsuser
533 | *- [Bb]ackup.rdl
534 | *- [Bb]ackup ([0-9]).rdl
535 | *- [Bb]ackup ([0-9][0-9]).rdl
536 |
537 | # Microsoft Fakes
538 | FakesAssemblies/
539 |
540 | # GhostDoc plugin setting file
541 | *.GhostDoc.xml
542 |
543 | # Node.js Tools for Visual Studio
544 | .ntvs_analysis.dat
545 | node_modules/
546 |
547 | # Visual Studio 6 build log
548 | *.plg
549 |
550 | # Visual Studio 6 workspace options file
551 | *.opt
552 |
553 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
554 | *.vbw
555 |
556 | # Visual Studio LightSwitch build output
557 | **/*.HTMLClient/GeneratedArtifacts
558 | **/*.DesktopClient/GeneratedArtifacts
559 | **/*.DesktopClient/ModelManifest.xml
560 | **/*.Server/GeneratedArtifacts
561 | **/*.Server/ModelManifest.xml
562 | _Pvt_Extensions
563 |
564 | # Paket dependency manager
565 | .paket/paket.exe
566 | paket-files/
567 |
568 | # FAKE - F# Make
569 | .fake/
570 |
571 | # CodeRush personal settings
572 | .cr/personal
573 |
574 | # Python Tools for Visual Studio (PTVS)
575 | *.pyc
576 |
577 | # Cake - Uncomment if you are using it
578 | # tools/**
579 | # !tools/packages.config
580 |
581 | # Tabs Studio
582 | *.tss
583 |
584 | # Telerik's JustMock configuration file
585 | *.jmconfig
586 |
587 | # BizTalk build output
588 | *.btp.cs
589 | *.btm.cs
590 | *.odx.cs
591 | *.xsd.cs
592 |
593 | # OpenCover UI analysis results
594 | OpenCover/
595 |
596 | # Azure Stream Analytics local run output
597 | ASALocalRun/
598 |
599 | # MSBuild Binary and Structured Log
600 | *.binlog
601 |
602 | # NVidia Nsight GPU debugger configuration file
603 | *.nvuser
604 |
605 | # MFractors (Xamarin productivity tool) working folder
606 | .mfractor/
607 |
608 | # Local History for Visual Studio
609 | .localhistory/
610 |
611 | # BeatPulse healthcheck temp database
612 | healthchecksdb
613 |
614 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
615 | MigrationBackup/
616 |
617 | # End of https://www.gitignore.io/api/osx,python,pycharm,windows,visualstudio,visualstudiocode
618 |
--------------------------------------------------------------------------------