From 13bc49fbb6f82166eeb3213c6e5d2f39fde47a86 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Wed, 24 Nov 2021 14:34:52 +0200 Subject: [PATCH] Changed 'sofa' url --- .gitignore | 2 +- IKEA_scraper/.venv/bin/yapf | 8 + IKEA_scraper/.venv/bin/yapf-diff | 8 + .../pip/__pycache__/__init__.cpython-39.pyc | Bin 640 -> 650 bytes .../pip/__pycache__/__main__.cpython-39.pyc | Bin 596 -> 606 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 761 -> 771 bytes .../__pycache__/build_env.cpython-39.pyc | Bin 9477 -> 9487 bytes .../__pycache__/cache.cpython-39.pyc | Bin 8318 -> 8328 bytes .../__pycache__/configuration.cpython-39.pyc | Bin 11134 -> 11144 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 16380 -> 16390 bytes .../__pycache__/pyproject.cpython-39.pyc | Bin 3700 -> 3710 bytes .../self_outdated_check.cpython-39.pyc | Bin 4513 -> 4523 bytes .../__pycache__/wheel_builder.cpython-39.pyc | Bin 9127 -> 9137 bytes .../cli/__pycache__/__init__.cpython-39.pyc | Bin 281 -> 291 bytes .../__pycache__/autocompletion.cpython-39.pyc | Bin 5138 -> 5148 bytes .../__pycache__/base_command.cpython-39.pyc | Bin 6144 -> 6154 bytes .../cli/__pycache__/cmdoptions.cpython-39.pyc | Bin 22574 -> 22584 bytes .../command_context.cpython-39.pyc | Bin 1296 -> 1306 bytes .../cli/__pycache__/main.cpython-39.pyc | Bin 1371 -> 1381 bytes .../__pycache__/main_parser.cpython-39.pyc | Bin 2168 -> 2178 bytes .../cli/__pycache__/parser.cpython-39.pyc | Bin 9952 -> 9962 bytes .../__pycache__/progress_bars.cpython-39.pyc | Bin 7628 -> 7638 bytes .../__pycache__/req_command.cpython-39.pyc | Bin 12363 -> 12373 bytes .../cli/__pycache__/spinners.cpython-39.pyc | Bin 4951 -> 4961 bytes .../__pycache__/status_codes.cpython-39.pyc | Bin 360 -> 370 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 3058 -> 3068 bytes .../__pycache__/install.cpython-39.pyc | Bin 17692 -> 17702 bytes .../commands/__pycache__/list.cpython-39.pyc | Bin 10156 -> 10166 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 804 -> 814 bytes .../__pycache__/base.cpython-39.pyc | Bin 1879 -> 1889 bytes .../__pycache__/installed.cpython-39.pyc | Bin 1326 -> 1336 bytes .../__pycache__/sdist.cpython-39.pyc | Bin 4652 -> 4662 bytes .../__pycache__/wheel.cpython-39.pyc | Bin 1604 -> 1614 bytes .../index/__pycache__/__init__.cpython-39.pyc | Bin 235 -> 245 bytes .../__pycache__/collector.cpython-39.pyc | Bin 15889 -> 15899 bytes .../__pycache__/package_finder.cpython-39.pyc | Bin 28104 -> 28114 bytes .../index/__pycache__/sources.cpython-39.pyc | Bin 7200 -> 7210 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 10615 -> 10625 bytes .../__pycache__/_distutils.cpython-39.pyc | Bin 4674 -> 4684 bytes .../__pycache__/_sysconfig.cpython-39.pyc | Bin 6265 -> 6275 bytes .../locations/__pycache__/base.cpython-39.pyc | Bin 1543 -> 1553 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 1930 -> 1940 bytes .../metadata/__pycache__/base.cpython-39.pyc | Bin 13009 -> 13019 bytes .../__pycache__/pkg_resources.cpython-39.pyc | Bin 6117 -> 6127 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 269 -> 279 bytes .../__pycache__/candidate.cpython-39.pyc | Bin 1452 -> 1462 bytes .../__pycache__/direct_url.cpython-39.pyc | Bin 7242 -> 7252 bytes .../__pycache__/format_control.cpython-39.pyc | Bin 2723 -> 2733 bytes .../models/__pycache__/index.cpython-39.pyc | Bin 1239 -> 1249 bytes .../models/__pycache__/link.cpython-39.pyc | Bin 10263 -> 10273 bytes .../models/__pycache__/scheme.cpython-39.pyc | Bin 1015 -> 1025 bytes .../__pycache__/search_scope.cpython-39.pyc | Bin 3484 -> 3494 bytes .../selection_prefs.cpython-39.pyc | Bin 1671 -> 1681 bytes .../__pycache__/target_python.cpython-39.pyc | Bin 3417 -> 3427 bytes .../models/__pycache__/wheel.cpython-39.pyc | Bin 4341 -> 4351 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 257 -> 267 bytes .../network/__pycache__/auth.cpython-39.pyc | Bin 7489 -> 7499 bytes .../network/__pycache__/cache.cpython-39.pyc | Bin 2899 -> 2909 bytes .../__pycache__/download.cpython-39.pyc | Bin 5488 -> 5498 bytes .../__pycache__/lazy_wheel.cpython-39.pyc | Bin 8389 -> 8399 bytes .../__pycache__/session.cpython-39.pyc | Bin 10759 -> 10769 bytes .../network/__pycache__/utils.cpython-39.pyc | Bin 1435 -> 1445 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 205 -> 215 bytes .../__pycache__/check.cpython-39.pyc | Bin 4009 -> 4019 bytes .../__pycache__/prepare.cpython-39.pyc | Bin 14661 -> 14671 bytes .../build/__pycache__/__init__.cpython-39.pyc | Bin 211 -> 221 bytes .../build/__pycache__/metadata.cpython-39.pyc | Bin 1195 -> 1205 bytes .../metadata_editable.cpython-39.pyc | Bin 1233 -> 1243 bytes .../metadata_legacy.cpython-39.pyc | Bin 2163 -> 2173 bytes .../build/__pycache__/wheel.cpython-39.pyc | Bin 1206 -> 1216 bytes .../__pycache__/wheel_editable.cpython-39.pyc | Bin 1422 -> 1432 bytes .../__pycache__/wheel_legacy.cpython-39.pyc | Bin 2722 -> 2732 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 269 -> 279 bytes .../editable_legacy.cpython-39.pyc | Bin 1447 -> 1457 bytes .../install/__pycache__/legacy.cpython-39.pyc | Bin 3507 -> 3517 bytes .../install/__pycache__/wheel.cpython-39.pyc | Bin 20971 -> 20981 bytes .../req/__pycache__/__init__.cpython-39.pyc | Bin 2564 -> 2574 bytes .../__pycache__/constructors.cpython-39.pyc | Bin 11322 -> 11332 bytes .../req/__pycache__/req_file.cpython-39.pyc | Bin 13382 -> 13392 bytes .../__pycache__/req_install.cpython-39.pyc | Bin 22761 -> 22771 bytes .../req/__pycache__/req_set.cpython-39.pyc | Bin 5902 -> 5912 bytes .../__pycache__/req_tracker.cpython-39.pyc | Bin 4262 -> 4272 bytes .../__pycache__/req_uninstall.cpython-39.pyc | Bin 18794 -> 18804 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 205 -> 215 bytes .../__pycache__/base.cpython-39.pyc | Bin 1062 -> 1072 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 216 -> 226 bytes .../__pycache__/base.cpython-39.pyc | Bin 6613 -> 6623 bytes .../__pycache__/candidates.cpython-39.pyc | Bin 18513 -> 18523 bytes .../__pycache__/factory.cpython-39.pyc | Bin 18375 -> 18385 bytes .../found_candidates.cpython-39.pyc | Bin 4847 -> 4857 bytes .../__pycache__/provider.cpython-39.pyc | Bin 7118 -> 7128 bytes .../__pycache__/reporter.cpython-39.pyc | Bin 3277 -> 3287 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 7586 -> 7596 bytes .../__pycache__/resolver.cpython-39.pyc | Bin 7302 -> 7312 bytes .../utils/__pycache__/__init__.cpython-39.pyc | Bin 200 -> 210 bytes .../utils/__pycache__/_log.cpython-39.pyc | Bin 1525 -> 1535 bytes .../utils/__pycache__/appdirs.cpython-39.pyc | Bin 1631 -> 1641 bytes .../utils/__pycache__/compat.cpython-39.pyc | Bin 1519 -> 1529 bytes .../compatibility_tags.cpython-39.pyc | Bin 4071 -> 4081 bytes .../__pycache__/deprecation.cpython-39.pyc | Bin 3257 -> 3267 bytes .../direct_url_helpers.cpython-39.pyc | Bin 2090 -> 2100 bytes .../__pycache__/distutils_args.cpython-39.pyc | Bin 1105 -> 1115 bytes .../utils/__pycache__/egg_link.cpython-39.pyc | Bin 2146 -> 2156 bytes .../utils/__pycache__/encoding.cpython-39.pyc | Bin 1309 -> 1319 bytes .../__pycache__/filesystem.cpython-39.pyc | Bin 5146 -> 5156 bytes .../__pycache__/filetypes.cpython-39.pyc | Bin 950 -> 960 bytes .../utils/__pycache__/glibc.cpython-39.pyc | Bin 1681 -> 1691 bytes .../utils/__pycache__/hashes.cpython-39.pyc | Bin 5195 -> 5205 bytes .../inject_securetransport.cpython-39.pyc | Bin 989 -> 999 bytes .../utils/__pycache__/logging.cpython-39.pyc | Bin 9295 -> 9305 bytes .../utils/__pycache__/misc.cpython-39.pyc | Bin 20942 -> 20952 bytes .../utils/__pycache__/models.cpython-39.pyc | Bin 2068 -> 2078 bytes .../__pycache__/packaging.cpython-39.pyc | Bin 2644 -> 2654 bytes .../utils/__pycache__/parallel.cpython-39.pyc | Bin 3215 -> 3225 bytes .../__pycache__/pkg_resources.cpython-39.pyc | Bin 1877 -> 1887 bytes .../setuptools_build.cpython-39.pyc | Bin 3439 -> 3449 bytes .../__pycache__/subprocess.cpython-39.pyc | Bin 6252 -> 6262 bytes .../utils/__pycache__/temp_dir.cpython-39.pyc | Bin 7267 -> 7277 bytes .../__pycache__/unpacking.cpython-39.pyc | Bin 6731 -> 6741 bytes .../utils/__pycache__/urls.cpython-39.pyc | Bin 1604 -> 1614 bytes .../__pycache__/virtualenv.cpython-39.pyc | Bin 3294 -> 3304 bytes .../utils/__pycache__/wheel.cpython-39.pyc | Bin 6283 -> 6293 bytes .../vcs/__pycache__/__init__.cpython-39.pyc | Bin 523 -> 533 bytes .../vcs/__pycache__/bazaar.cpython-39.pyc | Bin 3233 -> 3243 bytes .../vcs/__pycache__/git.cpython-39.pyc | Bin 12357 -> 12367 bytes .../vcs/__pycache__/mercurial.cpython-39.pyc | Bin 4862 -> 4872 bytes .../vcs/__pycache__/subversion.cpython-39.pyc | Bin 8395 -> 8405 bytes .../__pycache__/versioncontrol.cpython-39.pyc | Bin 20895 -> 20905 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 2913 -> 2923 bytes .../_vendor/__pycache__/distro.cpython-39.pyc | Bin 38375 -> 38385 bytes .../__pycache__/pyparsing.cpython-39.pyc | Bin 240444 -> 240454 bytes .../_vendor/__pycache__/six.cpython-39.pyc | Bin 27517 -> 27527 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 558 -> 568 bytes .../__pycache__/adapter.cpython-39.pyc | Bin 3084 -> 3094 bytes .../__pycache__/cache.cpython-39.pyc | Bin 1831 -> 1841 bytes .../__pycache__/compat.cpython-39.pyc | Bin 755 -> 765 bytes .../__pycache__/controller.cpython-39.pyc | Bin 7772 -> 7782 bytes .../__pycache__/filewrapper.cpython-39.pyc | Bin 2180 -> 2190 bytes .../__pycache__/serialize.cpython-39.pyc | Bin 4231 -> 4241 bytes .../__pycache__/wrapper.cpython-39.pyc | Bin 682 -> 692 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 302 -> 312 bytes .../__pycache__/file_cache.cpython-39.pyc | Bin 3318 -> 3328 bytes .../__pycache__/redis_cache.cpython-39.pyc | Bin 1574 -> 1584 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 284 -> 294 bytes .../certifi/__pycache__/core.cpython-39.pyc | Bin 1552 -> 1562 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 1908 -> 1918 bytes .../__pycache__/big5freq.cpython-39.pyc | Bin 27187 -> 27197 bytes .../__pycache__/big5prober.cpython-39.pyc | Bin 1142 -> 1152 bytes .../chardistribution.cpython-39.pyc | Bin 6228 -> 6238 bytes .../charsetgroupprober.cpython-39.pyc | Bin 2269 -> 2279 bytes .../__pycache__/charsetprober.cpython-39.pyc | Bin 3491 -> 3501 bytes .../codingstatemachine.cpython-39.pyc | Bin 2918 -> 2928 bytes .../__pycache__/cp949prober.cpython-39.pyc | Bin 1149 -> 1159 bytes .../chardet/__pycache__/enums.cpython-39.pyc | Bin 2656 -> 2666 bytes .../__pycache__/escprober.cpython-39.pyc | Bin 2641 -> 2651 bytes .../chardet/__pycache__/escsm.cpython-39.pyc | Bin 7090 -> 7100 bytes .../__pycache__/eucjpprober.cpython-39.pyc | Bin 2455 -> 2465 bytes .../__pycache__/euckrfreq.cpython-39.pyc | Bin 12071 -> 12081 bytes .../__pycache__/euckrprober.cpython-39.pyc | Bin 1150 -> 1160 bytes .../__pycache__/euctwfreq.cpython-39.pyc | Bin 27191 -> 27201 bytes .../__pycache__/euctwprober.cpython-39.pyc | Bin 1150 -> 1160 bytes .../__pycache__/gb2312freq.cpython-39.pyc | Bin 19115 -> 19125 bytes .../__pycache__/gb2312prober.cpython-39.pyc | Bin 1158 -> 1168 bytes .../__pycache__/hebrewprober.cpython-39.pyc | Bin 3027 -> 3037 bytes .../__pycache__/jisfreq.cpython-39.pyc | Bin 22143 -> 22153 bytes .../chardet/__pycache__/jpcntx.cpython-39.pyc | Bin 37616 -> 37626 bytes .../langbulgarianmodel.cpython-39.pyc | Bin 21818 -> 21828 bytes .../__pycache__/langgreekmodel.cpython-39.pyc | Bin 20494 -> 20504 bytes .../langhebrewmodel.cpython-39.pyc | Bin 20562 -> 20572 bytes .../langrussianmodel.cpython-39.pyc | Bin 26366 -> 26376 bytes .../__pycache__/langthaimodel.cpython-39.pyc | Bin 20738 -> 20748 bytes .../langturkishmodel.cpython-39.pyc | Bin 20578 -> 20588 bytes .../__pycache__/latin1prober.cpython-39.pyc | Bin 2963 -> 2973 bytes .../mbcharsetprober.cpython-39.pyc | Bin 2270 -> 2280 bytes .../mbcsgroupprober.cpython-39.pyc | Bin 1139 -> 1149 bytes .../chardet/__pycache__/mbcssm.cpython-39.pyc | Bin 15726 -> 15736 bytes .../sbcharsetprober.cpython-39.pyc | Bin 3123 -> 3133 bytes .../sbcsgroupprober.cpython-39.pyc | Bin 1708 -> 1718 bytes .../__pycache__/sjisprober.cpython-39.pyc | Bin 2491 -> 2501 bytes .../universaldetector.cpython-39.pyc | Bin 5839 -> 5849 bytes .../__pycache__/utf8prober.cpython-39.pyc | Bin 2000 -> 2010 bytes .../__pycache__/version.cpython-39.pyc | Bin 447 -> 457 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 452 -> 462 bytes .../colorama/__pycache__/ansi.cpython-39.pyc | Bin 3237 -> 3247 bytes .../__pycache__/ansitowin32.cpython-39.pyc | Bin 7703 -> 7713 bytes .../__pycache__/initialise.cpython-39.pyc | Bin 1719 -> 1729 bytes .../colorama/__pycache__/win32.cpython-39.pyc | Bin 3951 -> 3961 bytes .../__pycache__/winterm.cpython-39.pyc | Bin 4673 -> 4683 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 1065 -> 1075 bytes .../distlib/__pycache__/compat.cpython-39.pyc | Bin 31830 -> 31840 bytes .../__pycache__/resources.cpython-39.pyc | Bin 11019 -> 11029 bytes .../__pycache__/scripts.cpython-39.pyc | Bin 11251 -> 11261 bytes .../distlib/__pycache__/util.cpython-39.pyc | Bin 52614 -> 52624 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 1311 -> 1321 bytes .../__pycache__/_ihatexml.cpython-39.pyc | Bin 13780 -> 13790 bytes .../__pycache__/_inputstream.cpython-39.pyc | Bin 21639 -> 21649 bytes .../__pycache__/_tokenizer.cpython-39.pyc | Bin 39734 -> 39744 bytes .../__pycache__/_utils.cpython-39.pyc | Bin 4811 -> 4821 bytes .../__pycache__/constants.cpython-39.pyc | Bin 66349 -> 66359 bytes .../__pycache__/html5parser.cpython-39.pyc | Bin 91020 -> 91030 bytes .../__pycache__/serializer.cpython-39.pyc | Bin 10822 -> 10832 bytes .../_trie/__pycache__/__init__.cpython-39.pyc | Bin 361 -> 371 bytes .../_trie/__pycache__/_base.cpython-39.pyc | Bin 1605 -> 1615 bytes .../_trie/__pycache__/py.cpython-39.pyc | Bin 2266 -> 2276 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 3341 -> 3351 bytes .../__pycache__/base.cpython-39.pyc | Bin 11325 -> 11335 bytes .../__pycache__/etree.cpython-39.pyc | Bin 11830 -> 11840 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 4007 -> 4017 bytes .../idna/__pycache__/__init__.cpython-39.pyc | Bin 856 -> 866 bytes .../idna/__pycache__/core.cpython-39.pyc | Bin 9161 -> 9171 bytes .../idna/__pycache__/idnadata.cpython-39.pyc | Bin 22147 -> 22157 bytes .../idna/__pycache__/intranges.cpython-39.pyc | Bin 1869 -> 1879 bytes .../__pycache__/package_data.cpython-39.pyc | Bin 220 -> 230 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 1423 -> 1433 bytes .../__pycache__/_version.cpython-39.pyc | Bin 227 -> 237 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 1861 -> 1871 bytes .../msgpack/__pycache__/ext.cpython-39.pyc | Bin 6289 -> 6299 bytes .../__pycache__/fallback.cpython-39.pyc | Bin 26735 -> 26745 bytes .../__pycache__/__about__.cpython-39.pyc | Bin 599 -> 609 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 455 -> 465 bytes .../__pycache__/_manylinux.cpython-39.pyc | Bin 7303 -> 7313 bytes .../__pycache__/_musllinux.cpython-39.pyc | Bin 4618 -> 4628 bytes .../__pycache__/_structures.cpython-39.pyc | Bin 3091 -> 3101 bytes .../__pycache__/markers.cpython-39.pyc | Bin 9462 -> 9472 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 3983 -> 3993 bytes .../__pycache__/specifiers.cpython-39.pyc | Bin 22219 -> 22229 bytes .../packaging/__pycache__/tags.cpython-39.pyc | Bin 12298 -> 12308 bytes .../__pycache__/utils.cpython-39.pyc | Bin 3620 -> 3630 bytes .../__pycache__/version.cpython-39.pyc | Bin 13161 -> 13171 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 322 -> 332 bytes .../pep517/__pycache__/compat.cpython-39.pyc | Bin 1538 -> 1548 bytes .../__pycache__/wrappers.cpython-39.pyc | Bin 12502 -> 12512 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 924 -> 934 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 100345 -> 100355 bytes .../__pycache__/py31compat.cpython-39.pyc | Bin 659 -> 669 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 11083 -> 11093 bytes .../__pycache__/api.cpython-39.pyc | Bin 5311 -> 5321 bytes .../__pycache__/unix.cpython-39.pyc | Bin 7048 -> 7058 bytes .../__pycache__/version.cpython-39.pyc | Bin 304 -> 314 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 5691 -> 5701 bytes .../progress/__pycache__/bar.cpython-39.pyc | Bin 2736 -> 2746 bytes .../__pycache__/colors.cpython-39.pyc | Bin 1509 -> 1519 bytes .../__pycache__/spinner.cpython-39.pyc | Bin 1460 -> 1470 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 4011 -> 4021 bytes .../__pycache__/__version__.cpython-39.pyc | Bin 564 -> 574 bytes .../_internal_utils.cpython-39.pyc | Bin 1311 -> 1321 bytes .../__pycache__/adapters.cpython-39.pyc | Bin 16982 -> 16992 bytes .../requests/__pycache__/api.cpython-39.pyc | Bin 6728 -> 6738 bytes .../requests/__pycache__/auth.cpython-39.pyc | Bin 8340 -> 8350 bytes .../requests/__pycache__/certs.cpython-39.pyc | Bin 642 -> 652 bytes .../__pycache__/compat.cpython-39.pyc | Bin 1621 -> 1631 bytes .../__pycache__/cookies.cpython-39.pyc | Bin 18831 -> 18841 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 5414 -> 5424 bytes .../requests/__pycache__/hooks.cpython-39.pyc | Bin 999 -> 1009 bytes .../__pycache__/models.cpython-39.pyc | Bin 24479 -> 24489 bytes .../__pycache__/packages.cpython-39.pyc | Bin 511 -> 521 bytes .../__pycache__/sessions.cpython-39.pyc | Bin 19866 -> 19876 bytes .../__pycache__/status_codes.cpython-39.pyc | Bin 4248 -> 4258 bytes .../__pycache__/structures.cpython-39.pyc | Bin 4469 -> 4479 bytes .../requests/__pycache__/utils.cpython-39.pyc | Bin 23333 -> 23343 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 615 -> 625 bytes .../__pycache__/providers.cpython-39.pyc | Bin 6714 -> 6724 bytes .../__pycache__/reporters.cpython-39.pyc | Bin 2311 -> 2321 bytes .../__pycache__/resolvers.cpython-39.pyc | Bin 15268 -> 15278 bytes .../__pycache__/structs.cpython-39.pyc | Bin 7288 -> 7298 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 210 -> 220 bytes .../collections_abc.cpython-39.pyc | Bin 384 -> 394 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 16288 -> 16298 bytes .../__pycache__/_asyncio.cpython-39.pyc | Bin 2603 -> 2613 bytes .../__pycache__/_utils.cpython-39.pyc | Bin 1240 -> 1250 bytes .../tenacity/__pycache__/after.cpython-39.pyc | Bin 1219 -> 1229 bytes .../__pycache__/before.cpython-39.pyc | Bin 1107 -> 1117 bytes .../__pycache__/before_sleep.cpython-39.pyc | Bin 1399 -> 1409 bytes .../tenacity/__pycache__/nap.cpython-39.pyc | Bin 1201 -> 1211 bytes .../tenacity/__pycache__/retry.cpython-39.pyc | Bin 8789 -> 8799 bytes .../tenacity/__pycache__/stop.cpython-39.pyc | Bin 4253 -> 4263 bytes .../tenacity/__pycache__/wait.cpython-39.pyc | Bin 7965 -> 7975 bytes .../tomli/__pycache__/__init__.cpython-39.pyc | Bin 388 -> 398 bytes .../tomli/__pycache__/_parser.cpython-39.pyc | Bin 16363 -> 16373 bytes .../tomli/__pycache__/_re.cpython-39.pyc | Bin 2438 -> 2448 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 2198 -> 2208 bytes .../__pycache__/_collections.cpython-39.pyc | Bin 10793 -> 10803 bytes .../__pycache__/_version.cpython-39.pyc | Bin 222 -> 232 bytes .../__pycache__/connection.cpython-39.pyc | Bin 13691 -> 13701 bytes .../__pycache__/connectionpool.cpython-39.pyc | Bin 24718 -> 24728 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 11655 -> 11665 bytes .../urllib3/__pycache__/fields.cpython-39.pyc | Bin 8170 -> 8180 bytes .../__pycache__/filepost.cpython-39.pyc | Bin 2771 -> 2781 bytes .../__pycache__/poolmanager.cpython-39.pyc | Bin 15173 -> 15183 bytes .../__pycache__/request.cpython-39.pyc | Bin 5634 -> 5644 bytes .../__pycache__/response.cpython-39.pyc | Bin 20845 -> 20855 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 208 -> 218 bytes .../_appengine_environ.cpython-39.pyc | Bin 1428 -> 1438 bytes .../contrib/__pycache__/socks.cpython-39.pyc | Bin 5644 -> 5654 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 322 -> 332 bytes .../packages/__pycache__/six.cpython-39.pyc | Bin 27592 -> 27602 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 581 -> 591 bytes .../util/__pycache__/__init__.cpython-39.pyc | Bin 1118 -> 1128 bytes .../__pycache__/connection.cpython-39.pyc | Bin 3470 -> 3480 bytes .../util/__pycache__/proxy.cpython-39.pyc | Bin 1354 -> 1364 bytes .../util/__pycache__/queue.cpython-39.pyc | Bin 1073 -> 1083 bytes .../util/__pycache__/request.cpython-39.pyc | Bin 3461 -> 3471 bytes .../util/__pycache__/response.cpython-39.pyc | Bin 2358 -> 2368 bytes .../util/__pycache__/retry.cpython-39.pyc | Bin 15845 -> 15855 bytes .../util/__pycache__/ssl_.cpython-39.pyc | Bin 11342 -> 11352 bytes .../__pycache__/ssltransport.cpython-39.pyc | Bin 7523 -> 7533 bytes .../util/__pycache__/timeout.cpython-39.pyc | Bin 8956 -> 8966 bytes .../util/__pycache__/url.cpython-39.pyc | Bin 10681 -> 10691 bytes .../util/__pycache__/wait.cpython-39.pyc | Bin 3141 -> 3151 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 9732 -> 9742 bytes .../__pycache__/labels.cpython-39.pyc | Bin 3846 -> 3856 bytes .../yapf-0.31.0.dist-info/AUTHORS | 9 + .../yapf-0.31.0.dist-info/INSTALLER | 1 + .../yapf-0.31.0.dist-info/LICENSE | 202 ++ .../yapf-0.31.0.dist-info/METADATA | 1026 ++++++ .../yapf-0.31.0.dist-info/RECORD | 109 + .../yapf-0.31.0.dist-info/REQUESTED | 0 .../site-packages/yapf-0.31.0.dist-info/WHEEL | 6 + .../yapf-0.31.0.dist-info/entry_points.txt | 4 + .../yapf-0.31.0.dist-info/top_level.txt | 2 + .../python3.9/site-packages/yapf/__init__.py | 369 ++ .../python3.9/site-packages/yapf/__main__.py | 18 + .../yapf/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 9693 bytes .../yapf/__pycache__/__main__.cpython-39.pyc | Bin 0 -> 265 bytes .../site-packages/yapf/yapflib/__init__.py | 13 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 203 bytes .../blank_line_calculator.cpython-39.pyc | Bin 0 -> 5542 bytes .../comment_splicer.cpython-39.pyc | Bin 0 -> 6874 bytes .../continuation_splicer.cpython-39.pyc | Bin 0 -> 1437 bytes .../yapflib/__pycache__/errors.cpython-39.pyc | Bin 0 -> 589 bytes .../__pycache__/file_resources.cpython-39.pyc | Bin 0 -> 7315 bytes .../format_decision_state.cpython-39.pyc | Bin 0 -> 26609 bytes .../__pycache__/format_token.cpython-39.pyc | Bin 0 -> 12893 bytes .../identify_container.cpython-39.pyc | Bin 0 -> 1840 bytes .../__pycache__/line_joiner.cpython-39.pyc | Bin 0 -> 2714 bytes .../__pycache__/object_state.cpython-39.pyc | Bin 0 -> 9343 bytes .../__pycache__/py3compat.cpython-39.pyc | Bin 0 -> 3067 bytes .../pytree_unwrapper.cpython-39.pyc | Bin 0 -> 12915 bytes .../__pycache__/pytree_utils.cpython-39.pyc | Bin 0 -> 9361 bytes .../__pycache__/pytree_visitor.cpython-39.pyc | Bin 0 -> 4762 bytes .../__pycache__/reformatter.cpython-39.pyc | Bin 0 -> 18401 bytes .../__pycache__/split_penalty.cpython-39.pyc | Bin 0 -> 16490 bytes .../yapflib/__pycache__/style.cpython-39.pyc | Bin 0 -> 23363 bytes .../subtype_assigner.cpython-39.pyc | Bin 0 -> 14179 bytes .../__pycache__/unwrapped_line.cpython-39.pyc | Bin 0 -> 13935 bytes .../__pycache__/verifier.cpython-39.pyc | Bin 0 -> 2408 bytes .../__pycache__/yapf_api.cpython-39.pyc | Bin 0 -> 9345 bytes .../yapf/yapflib/blank_line_calculator.py | 177 + .../yapf/yapflib/comment_splicer.py | 365 ++ .../yapf/yapflib/continuation_splicer.py | 52 + .../site-packages/yapf/yapflib/errors.py | 23 + .../yapf/yapflib/file_resources.py | 265 ++ .../yapf/yapflib/format_decision_state.py | 1254 +++++++ .../yapf/yapflib/format_token.py | 385 ++ .../yapf/yapflib/identify_container.py | 67 + .../site-packages/yapf/yapflib/line_joiner.py | 109 + .../yapf/yapflib/object_state.py | 235 ++ .../site-packages/yapf/yapflib/py3compat.py | 131 + .../yapf/yapflib/pytree_unwrapper.py | 424 +++ .../yapf/yapflib/pytree_utils.py | 346 ++ .../yapf/yapflib/pytree_visitor.py | 135 + .../site-packages/yapf/yapflib/reformatter.py | 800 +++++ .../yapf/yapflib/split_penalty.py | 629 ++++ .../site-packages/yapf/yapflib/style.py | 849 +++++ .../yapf/yapflib/subtype_assigner.py | 509 +++ .../yapf/yapflib/unwrapped_line.py | 673 ++++ .../site-packages/yapf/yapflib/verifier.py | 93 + .../site-packages/yapf/yapflib/yapf_api.py | 319 ++ .../site-packages/yapftests/__init__.py | 13 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 200 bytes .../blank_line_calculator_test.cpython-39.pyc | Bin 0 -> 8671 bytes .../comment_splicer_test.cpython-39.pyc | Bin 0 -> 8800 bytes .../file_resources_test.cpython-39.pyc | Bin 0 -> 16564 bytes .../format_decision_state_test.cpython-39.pyc | Bin 0 -> 3126 bytes .../format_token_test.cpython-39.pyc | Bin 0 -> 2515 bytes .../line_joiner_test.cpython-39.pyc | Bin 0 -> 3012 bytes .../__pycache__/main_test.cpython-39.pyc | Bin 0 -> 5548 bytes .../pytree_unwrapper_test.cpython-39.pyc | Bin 0 -> 9304 bytes .../pytree_utils_test.cpython-39.pyc | Bin 0 -> 7313 bytes .../pytree_visitor_test.cpython-39.pyc | Bin 0 -> 3657 bytes .../reformatter_basic_test.cpython-39.pyc | Bin 0 -> 93805 bytes .../reformatter_buganizer_test.cpython-39.pyc | Bin 0 -> 80291 bytes .../reformatter_facebook_test.cpython-39.pyc | Bin 0 -> 14233 bytes .../reformatter_pep8_test.cpython-39.pyc | Bin 0 -> 29269 bytes .../reformatter_python3_test.cpython-39.pyc | Bin 0 -> 13009 bytes ...formatter_style_config_test.cpython-39.pyc | Bin 0 -> 6120 bytes .../reformatter_verify_test.cpython-39.pyc | Bin 0 -> 3208 bytes .../split_penalty_test.cpython-39.pyc | Bin 0 -> 4809 bytes .../__pycache__/style_test.cpython-39.pyc | Bin 0 -> 12797 bytes .../subtype_assigner_test.cpython-39.pyc | Bin 0 -> 6369 bytes .../unwrapped_line_test.cpython-39.pyc | Bin 0 -> 3956 bytes .../__pycache__/utils.cpython-39.pyc | Bin 0 -> 1445 bytes .../__pycache__/yapf_test.cpython-39.pyc | Bin 0 -> 56085 bytes .../yapf_test_helper.cpython-39.pyc | Bin 0 -> 2403 bytes .../yapftests/blank_line_calculator_test.py | 422 +++ .../yapftests/comment_splicer_test.py | 334 ++ .../yapftests/file_resources_test.py | 493 +++ .../yapftests/format_decision_state_test.py | 145 + .../yapftests/format_token_test.py | 88 + .../yapftests/line_joiner_test.py | 82 + .../site-packages/yapftests/main_test.py | 144 + .../yapftests/pytree_unwrapper_test.py | 356 ++ .../yapftests/pytree_utils_test.py | 205 ++ .../yapftests/pytree_visitor_test.py | 120 + .../yapftests/reformatter_basic_test.py | 3140 +++++++++++++++++ .../yapftests/reformatter_buganizer_test.py | 2350 ++++++++++++ .../yapftests/reformatter_facebook_test.py | 432 +++ .../yapftests/reformatter_pep8_test.py | 919 +++++ .../yapftests/reformatter_python3_test.py | 471 +++ .../reformatter_style_config_test.py | 198 ++ .../yapftests/reformatter_verify_test.py | 108 + .../yapftests/split_penalty_test.py | 266 ++ .../site-packages/yapftests/style_test.py | 336 ++ .../yapftests/subtype_assigner_test.py | 304 ++ .../yapftests/unwrapped_line_test.py | 96 + .../site-packages/yapftests/utils.py | 89 + .../site-packages/yapftests/yapf_test.py | 2038 +++++++++++ .../yapftests/yapf_test_helper.py | 89 + IKEA_scraper/__pycache__/ikea.cpython-39.pyc | Bin 5212 -> 5235 bytes IKEA_scraper/ikea.py | 8 +- task_241121/main.py | 29 + 421 files changed, 22889 insertions(+), 3 deletions(-) create mode 100755 IKEA_scraper/.venv/bin/yapf create mode 100755 IKEA_scraper/.venv/bin/yapf-diff create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/AUTHORS create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/INSTALLER create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/LICENSE create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/METADATA create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/RECORD create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/REQUESTED create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/WHEEL create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/entry_points.txt create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/top_level.txt create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/__init__.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/__main__.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/__pycache__/__init__.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/__pycache__/__main__.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__init__.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/__init__.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/blank_line_calculator.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/comment_splicer.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/continuation_splicer.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/errors.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/file_resources.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/format_decision_state.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/format_token.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/identify_container.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/line_joiner.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/object_state.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/py3compat.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/pytree_unwrapper.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/pytree_utils.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/pytree_visitor.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/reformatter.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/split_penalty.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/style.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/subtype_assigner.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/unwrapped_line.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/verifier.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/yapf_api.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/blank_line_calculator.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/comment_splicer.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/continuation_splicer.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/errors.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/file_resources.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/format_decision_state.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/format_token.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/identify_container.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/line_joiner.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/object_state.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/py3compat.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/pytree_unwrapper.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/pytree_utils.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/pytree_visitor.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/reformatter.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/split_penalty.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/style.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/subtype_assigner.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/unwrapped_line.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/verifier.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/yapf_api.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__init__.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/__init__.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/blank_line_calculator_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/comment_splicer_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/file_resources_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/format_decision_state_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/format_token_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/line_joiner_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/main_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/pytree_unwrapper_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/pytree_utils_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/pytree_visitor_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_basic_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_buganizer_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_facebook_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_pep8_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_python3_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_style_config_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_verify_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/split_penalty_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/style_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/subtype_assigner_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/unwrapped_line_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/utils.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/yapf_test.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/yapf_test_helper.cpython-39.pyc create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/blank_line_calculator_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/comment_splicer_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/file_resources_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/format_decision_state_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/format_token_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/line_joiner_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/main_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/pytree_unwrapper_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/pytree_utils_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/pytree_visitor_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_basic_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_buganizer_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_facebook_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_pep8_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_python3_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_style_config_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_verify_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/split_penalty_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/style_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/subtype_assigner_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/unwrapped_line_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/utils.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/yapf_test.py create mode 100644 IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/yapf_test_helper.py create mode 100644 task_241121/main.py diff --git a/.gitignore b/.gitignore index c18c6fcf..1ec9e8da 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .vscode/ /__pycache__/ -.venv/ +/.venv/ diff --git a/IKEA_scraper/.venv/bin/yapf b/IKEA_scraper/.venv/bin/yapf new file mode 100755 index 00000000..547508c1 --- /dev/null +++ b/IKEA_scraper/.venv/bin/yapf @@ -0,0 +1,8 @@ +#!/home/kristofers/Documents/python/School/IKEA_scraper/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from yapf import run_main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run_main()) diff --git a/IKEA_scraper/.venv/bin/yapf-diff b/IKEA_scraper/.venv/bin/yapf-diff new file mode 100755 index 00000000..f6aa1c67 --- /dev/null +++ b/IKEA_scraper/.venv/bin/yapf-diff @@ -0,0 +1,8 @@ +#!/home/kristofers/Documents/python/School/IKEA_scraper/.venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from yapf.third_party.yapf_diff.yapf_diff import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/__pycache__/__init__.cpython-39.pyc index 38fd6b7d12dba87f1883d9605bf4b3cd4817f1cf..a87a8738f3d9f0da5a276c93a3718d61c44df7a9 100644 GIT binary patch delta 122 zcmZo*?PBFltTEI>kl HiG>*ejs+ZQ delta 90 zcmeBTZD8e2Rqi#KwoGcw+qT+C=9%>fko6|0|{nv$8Q?~z!P;!>1ZmZ~36 enNc$N3}Xx<*JMp5BTsCsQvsF*C1-9jNFQ xYdna3izT%pvt%Vhkpxf-O#F(~&rMCqOw{*CEJ|@H$}CIO52(y2nf#Km6acHPA{PJv diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/__init__.cpython-39.pyc index 25b536baa2b945327b7ad7759c18dcd642b1b237..34d518183c8a26cdc178f9171ba579004302dc93 100644 GIT binary patch delta 75 zcmey#+RVnC$ji&c00i06^EPrHU{om7&&bbB)z2=`^n0k$ji&c00ckI7jNV~z$likpPQPJnW*oPSd`*Ylv$RlA5fW5GWj)QBjc^f RxlGzXawd};klexK4FI&@7MTD5 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/build_env.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/build_env.cpython-39.pyc index cb05931eca031db9f8fa34c10719f76b00eb1401..89bb08809ec6c2ab8b7efe494cdacc0a82c424e5 100644 GIT binary patch delta 930 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 DRjI84 delta 671 zcmZWn-)qxQ6!s=D#@0HeYg6sYIz?S4ZK=*}4Qr}Hh7YpsRa7u-vL(!panso!p(w2m z1>epe;JbpXMDT5IKKSIT7XJg0%{}=r(Q}p|h!^tRlka@@oG&ML^9kF395y16&=Fie zKe_$zTQTnBYnJI4`CA4zZ*u36m0xPvb^nWadxQ<(VtP-0fNE}l5l;A1V?9}}(EA0r zKAd1x_kX*%_!qDG|gFq6?C4QHow6VdzgbSk=#5doHjx^wUxQ!}Jtm4cMPKJ5L7&$8D==IxCi2 z=Q%2HG_dGl%HHTjE0k&cwHH9O+LY!4rCkfxc~r!1u(Jz delta 124 zcmew-^F@X`k(ZZ?0SJDaFW$&~mr*Q3KQ}ccGg03ou_(o*D6=e8KcF(BWHSd-5|`;M z-i*ZJ_=3uUqWrAXSlbN~PV diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-39.pyc index 2b222e86dff56ba8c51a28875c373dd9a6e68346..cb08b28011f5fbe030276b088431638dc24e68d1 100644 GIT binary patch delta 732 zcmY+B&ubGw6vs2kW`7v-qXqNBT1{J_U22U&f+V2EV$H!~5u(T{%_D|50C(rw*c=Ejsfw-_A-h1oA z8F5AGT7zuLJK9G50tT)EOqItib}?`baS0G9g1!+E87{Y$QVYnA)b#ZmO-#hSmQX^s z0;s|t=m4D*R+6NU;+3$g-z3F0#3E$?3M`k&FUB@G2!9%GvU(3P9+`yW)_f0v_j2C1 zj6~N=@=kbkzD*kY5R0@|Afm(kc;vj`F2>cV==<#Td<`8&O@!l7UYEbJN9t{C*_4&s zhI)XeDciZmy9a1?09MZNL2B2fgC1Vf%1oR|Z!svA2-TVE6kqQlx`%*B9XkGia^6KJ z$En8zU6fiym-TIT;r5)M$6QFZH0+=6dxQT3N##GSzJNBS$#EsVirAE=`KlT}q$z*r zTjWWYE@a5#I?gjjR2;I=2(e`@={OEro9ty zyc9XtUMP4W!a#x_L%s3p-1#lUE6a^!~ibAc=g`(NUO*z;Yd=Mrz1_{Z3}J9|diH|ce;A?%}f)kgYY!9<9& zv3v_P*onNevLY;8PpC`r*bi`)X^uKGif>F?*z;ogvDiUqgK_1uc@b;|zydT`O>Lu9 z)>E6;7C~4OuoaS}*Z{!+ToB+g#V;vG<9urNUQN&yR@KgLZi6EXl|vn_%L0~o6HP!v zW>rGw0$EOwHR=KJ4;JD8E z<@WG49Qy*i>_=kNL4dshw8@RBKOLMF%2ov1neQoUZx62f5UPy*$isv@%JL8##uT51 za`wBtbdIZ#Z4`R{O<$_Ktzi*k+XVV2HNYx6saT2y$949rvV|U}71KcXIzr+41k*e5 rWFm@P2af|l7XZIewht~3<2WENBUc`}!4Xaf6vQFDwWVunsBl-n3x#QXmG7=w(X9N`>ThmvK9#V2gFmm z_~lUk;fc4CdSiDUw$x6c?K!;_}AEy{m{QIu^b)@op`e%13BCcWWp;VRL+;QlFn7F ztyK-JXmH45$UlNouoYSq`91NPlE46iMf+{ABLx+?EF7wB;m`sF1EDu;!~PIjmS#3Y z83YJHfrQWX2aiZl2#*N`JQ=BlOH|-JQ_#!VtqVUHdx8t2$8zCxNd;N>ReXW|HwBzv zlQ+}z8MUaDYP?>C8W%^vd6q?0^ zz9WLfaBm)SR9GW~2}#0j0*xN#1svRnO|dM#h$SN(68pUfO~K>Xj3@6#e_|%njAhwU8k!5po3A V65TX#Z;xw^<_|P2=;H6Gqkpjx#9IIW delta 741 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 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-39.pyc index 3f4904fdffbddddfb44a6b968134e60d7ea7f65c..344ef3818f33067511fef0cf62a9ed778e05d2f8 100644 GIT binary patch delta 2852 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 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-39.pyc index bddd4ffb2e8d7a17fb16cef8d63a735a962031e6..e933f0cb56f4e62b09bdb995504548266a79c0e5 100644 GIT binary patch delta 58 zcmbQhHH(Wok(ZZ?0SL0C=WXP^&8SeLpOK%Ns-InySzMBzmReM-?~_A~~SWUxoS^`MIh3*+rSfCHZNoMaB9q`N^fZsd**E`URCG8Iz|n z2Qx}fe#xwBD-Bey$>^skaf>}ZJ|#anKE6m4D0GWGCqF$sGcUbJ2*@kq0|~K}R2G0l zm_Q=TKq6{#FpC<{eN`;VKyn_743ON-;-?}BQq5dkQgn+sGq0owWChq=NQC@kT~<8+ DHpxWK delta 229 zcmaFLb(@Pjk(ZZ?0SJDaFW$(#n~Cw(R6t6VfkYHPP7}W~#kZJqi_;;ZAVtV_O;%xdX43(gsyR8AU6(Ox@@)1L#;8dgHUc0| KqA2y@&;bCsDO}C~ delta 307 zcmZn?{2{=d$ji&c00ckI7jNXYW%j(qWMuw}Q9+aO7JG4NZf;^xr6%(&COv~9VW6U0 zJjwY$vAmS{%)GSxl?+AFK*3*m`njnonTh%yiA5<0C6i|}-x0Ybn46fL z8lPWKl9`_upI($-T5xM}H;cdYEspfmJdk*Ckvh-}ut5+)X7g8;Rz^mJ$<=JZ32Goq z*@{wg^UG2-If}GEN;N=Y{6OugMTt33ql<5GCKja^$EW5Lr{3a7&P|EWOUzBZ#hPB4 zT3mdKIkz|+A_`K3Y}aHxc4sytkg58U%h`1qZ%tmxo&qGfIBWz!enU|k#-RfM`0ZbF diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/parser.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/parser.cpython-39.pyc index 2eed8781f1a50834c513a87c79e3cf3d593b2b7e..11fc65370f973f005b25edd5b468724f4aa76fa0 100644 GIT binary patch delta 1086 zcmY+DO=uHQ5XXH>yj0M@{xUQB-n^N4|NS`dZ9unz z!KxMVH{E*siT>0Z7O^Qi%VX1!7LJ|dAY!}h$wHRr91+VGovG40?;TAy0z2(&*2*P> zffuUAn1P?GUa~%1(tomkyjeZ6d8f=7^|%!xpGi9qC(j41@(=bA`X!9Y9G^8a=^PiZ zmV*0nUGRanhs?dD_ra`(^}Q{&LaV+7UAWjr6=6QQ$Re~LSnMcg3k zq(oFxZMt4L&vGVe-SsDU(kf&exP|vSUv((0SGal}q-M;5uu>dO(>hH!a{d5kaIve4 zUBgn>2J3&Bm8Gj>MwPg}3ER#k<=RnFT?OHboc_cr-medz9z^hSm>Roq21BjE=6Xx!?u>JL~TWFIL! OTU(DW8Y=NoWYZti!WtO> delta 1026 zcmY+DO-NKx6vw+WaqvGf&QYT7n-0 zN}Im$1lmdrAzCQKSVR#-t9G?%b7|owh(4fI2!V9Z8>1Y!zq$9!x&M3ax&Qgvxz(xa zkx0Ql`PqK&JXN3h%gjWY8>XIU*TFaq<|I$_OkH)eTmCgg6`@mhI<036N8sIpAtvy9 z!5h|r>*_Dojcefn)`~mf%IYqu2i+1PKf|wSmYLxW9HiiRY>uoe=V;oQ{TxaASR3|6 z4K|D~qV-bmQ#8RwFhJRUH>7dRQVJglhRE3hhY_U>aPr!Qdbw z4o}hzG}Gm2N2q_7V|)t6XhU!}0(1DJYKa-y_UgVs@lBHS0UavX3qI{j;6}ybLW9?0(FM=uV>aGjB zwdWM_E#2iBmpbzPzhei~CEDusHkqxfE%YV47k@xeIud3{Dqz{V0n~F?AcP2>A(E)o z*S2t4dqu3$?1n^K$#u*x`;}9wl~EBi_^3W%x$p=#>)+P3Qf8h|$3YrHn{f0L2YO$j zIIiq3zydBeG_VzX-EdUj>!qAOJuguuA~0gx7F5aUf2O5IKpr7TSR@1pNrHFF4VtYG zJYP!_8IAGShz!JQyfZ}5vQsHDlgjCqQ|dgfHy)RNo-d6Jl98r<#VhU>noY4vO=gI2 T&e}aXIPxCkTNuHIP3?aGF76Y9 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-39.pyc index ef30d2094c59b8579942b8be2f990cbd2458edb0..e09d770e39660e8fcb8c251fe19247ad35a96f2b 100644 GIT binary patch delta 2003 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 delta 1373 zcmZvcTW=dx5XU)o>Ns&OZelxi8;3NsvDdly1@(oCcqlXoh)98iMn%rXyKxrmU1xS( zHBHmFLQpOe(43ZrgojF1skroktoi~xa1liUB!om&=~R3Iz5ocRV*YDr5n`qN?aZ8+ zb7uC;IXC8hn2YJ1o$dGV^ZQTkr?Krw$}Ut*!_o^AIvEGaI%XE0US9P4Un5sqgz{gB zT?>mT`9QaqIm|)y4Dc-Q91sSI40*OEk)~OeR`_*W7|~EmB(TtZ>#2m_8J`aAKFW4_ zl%c}zva6!Cita5qRHZq&+Vg@a`?q?=gs}X!L|$~-?Dt`as)$*Xk0ej^JsfGtQ+zLd#E z-hle1+{oM%YqB%KviTez`hI!#-tXbvrv#Lt;?N*sX~KA)oYb)hqE@!nrR!R zU9vcL38!0YsZNW7sR|eDa z_F(++V`odNn`kD-qZuxi({&lNpu7)tt^xvUT?@@wr0Hgx5)lV5R=)=FK7jg-jLJ(J?B&^NGzYh=>5P`erI7aXBG zzmgE$Y>(@ZzLPKKPw#q%#mPx6#P0z8>$Z^nBYR^r@I&v=w44~pJ@hujD9{SvWYZqt zGOzmw_BaNxB=!EK~kD^9s=+2!Ddp^`j0`mj)PYcwrp z{cEF730A`6!_55napu~1pZsjRBcw8D(e`fust@1R!~iM``nQ4izRwyUBmJ=CGLq4K1>pJdb-f zn;nQLI{6{5@Z=&MGc_9^SCg|y93(0MA|yeC6o{|_5&9s)4rCsq_2iE{qKwv?*?AKg z*_=V*PLuQa)ELbtPvwhba{&oB1Fevl%)@UY2-kdzB`H5Yr^tMBAU_u)(5*27+Kl#- zJAkD1&efB|eSx@`14wW%im(Z=^061$Y!>8A zWMp#zsdJuO!KcP(F?l{;B%3Qpzy)Zd#AGpk6G6CPw^)+$^K*(UHb?VwF#?^PCZNse zFnJP?w3)n5pp7wPva8?}Q6G?Q2M__WvB(cZ_)mT(sL2>GSwcuwIRGf2DRql0IX|x? ywW1^^GpR@mu22QUa-AF@)G6QqVuIXTBn={LCVv!?V+#Q>112Z%i%-@OHU$7uR8*<} diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-39.pyc index d952d3e4137defe441cd1ddc9f5109a02ac4564a..f49a0be83277823420a104a659d54ef71bc73361 100644 GIT binary patch delta 134 zcmaFC^ofZ(k(ZZ?0SL0C=S}2p%#RWY^9%|Jb@Xxd3yb&j4~cj45A}12k_ZTL4fFI5 z4UTsT_4ILxckv90cMS^i4~i1-^N;s+3~}~w4Th*)$xs9`5KR24)X&JzP1VmX$}BF) bPfIN-)_2KIF3nBND=F45s4U5t_^})SG21FA delta 124 zcmeyw^n!^yk(ZZ?0SJDaFP_NVn0iYj%rht?)X~S)FD%~AKP2AGKh)3VmPA01YnZ2h zXmGq!sHcxhyo+a0ylYU9f6y%fKmT}N#}H=^*IEyq)HSO<+^l z23`wI;G1v)Y=}Ich)2K|5d$}*W8jUn1ALbbfDO3??92PW5BU(dt{~v8!mD4(YQ@$( z(v2{2ysVH!LBwJQV`x;lQCIyeRbZJ+Wl0!1v}a1RoMO#Xc$QYvJ8gb%h6|LCcnS7x z!zCb$Jmg}Bu}mF@k2$&kvcZLQMnd1}(169H?NerL5jP3_C}!4qFFs2L+NH4wN>iXi zi|O>L(BHLHFKD-Ma7vfBnT$!-r?kxfQpfKxQyi&z)t+!MVLlo=v!U?_wX~&MrDZ;T zDpL{ih>H-NO&|0+9Q&%TtPMwsET-8cLQWKs*ogxYF_7`CDDV9@kl#dWX}$RT2c7kT Ac>n+a delta 434 zcmYk1KTE?v7{=TDZBwFlv6FjKE3t#M4lZi7V-ax@&ofCedd@Du3f zmv9mU7vTmM-P{C0#KHH{4&LzN?tP#4dEWc2d{#=>wyhkT?5*XTW)z(+Rq3RA)k5(v4!-` ps>2swtlCm$sq&bKX@qbT(HO@ejX22UR!q+RGn7AJ&9qs1_yeZ#i>Lqq diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/install.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/install.cpython-39.pyc index 97d8b10c1bbfaf4d333893c6755e6a8de48b26ab..c8cbf7476627db24fed5e1381ae402f0377f7523 100644 GIT binary patch delta 2701 zcmZ`*U2I%O751#xyS5kG8z8S)_GbGxgpjpr`n1>t6CHs)>CF1BqXKsL(}qVxdK{Mb%`~Qi zjT5O=0# zjzzJ(Ly;gpiB)z-^yTb**^uo~;vq$Du^P42b7cyc-+-k4XZFxtCQ!`8roHS)DlQjP@I>W=K2@VQ?<=6)Fa-><*=%}}xse@fw#pD<)Y_0VIaGLS%2Ou=qp2+ z4Fn>hmK85mkh-sb=Qi2?zJhO35Z*CXfkV&fx&Ca*)Z+pNpplyHKQB_|#=Zc>M6LU- zMIjdT(vDAVK8G~~HzpY`;9}P6xb~kN!(#l)uq7*;x#v!^;MpOBc)@0dpG2rDfM<=H z$GITD*Dz|d%T>Ch&sZ7p6@Ag_-(*g2O$zKJ^-U{tN~Tugqb=~DzJ?hzV;x9Ql9z=* z-^0B34&3DvH(HbP4K|UvfY0llyB5St`t!qE^^ILO_k9bNOAJwqI_D^JqpcX3lwN|( z%&%`8!>9ENyHAP7YGR-ZEj7F6MbUPV4OV0Q(m$i$-1}tW8MwZt=LWkz@;Zx=XtkOQ z74%hD%zDiZxuNUWo?*pmudn$_*dJqH1_m=+-oF{#wjbf5)`F@iZh&Q{N!> zt8MC03@_-5`|e--pB6SVJ0FDCtAHOv@qePg{xiU87UtNlvhHN8p&>w+hGa~v`F}Uj zOt4#x$$H;>lu!2y{jac!x}lFzy^ss*qyA9e9zHr`dM!3#HF9lwUew69*F>a0BF3Gm zM4NSbWb=THWI$hoXpXhtraxnTqW{)%c9|{A>l7S{wTlPe5)xD7`qJ?^RShVOF>bw;T*(xQzcI)bzgR>)Q$Vjli6AoV`3^r3ei^?n%;UN)+o#y; zS#Uq3Up;bn8-`Y#o!Z0(o8HqDgydHEpz1T= z`VYWw8Dtvo@5;jbE>I}b6-6c2Jf4BktYrc7mi5{36T6mKw3?1jO&y=I;#2&wPSQIt ze;r_&;ZGs`r9uCF{3KuMBln!b<9p8^7%7LJB1^f$x|ZwI@8tIID0}R$jLj1RpZFc- mT>=~c;0o3+v0?uzhNvMzH4xaKZv&9gnp_QuBl^O`(tiO+Lf44^ delta 2689 zcmZ`*Yiv|S6z*)>-L^~1DlLW5+LkuJr9f#Zw7iP6r78-d5siwu-rk*Uuf4nXGWV9Y z3RL0?F`6`^(L{~$heQ%l$tp3veqcKd>dcqo84MyaDRL|bKZ02 zoHO_EA@tTVeawm(*}o+v76*`ecQM0fUd#gmMw z>>Y`ntP(7-5&W1v#aQb23RjW_o@Y z>k@{o&+oT#myP!%Ch z`{uxi<0j3dBZLF-xZu0ZP+0ab7s3N2nu2E`Hqpi?QzgFOz9opThX{G4(IL)V)3)p( zuI0p5@Zeuu2IvP|Phc=LmxSzLQ&!d8ybxzFm{>x8MrG3ZcMzJay2`KtI z!Mp=-m#nBCh(b=Rm3!)!Hf_NYAy37cbb`1NGmlvw8S6} zOX9HkXU_v$yaKI?V8|QQUBd_Hu2qaY z26W@OvYa3h(UE<;c|VKm9(@gjE!jnjCK$U@9$vg{?mk#yG=Nl560Ml4AQLxfBc}k6>45WyZy%rjJ@8<75U^)CpWCGb|pFlScD|zR0tDLv)tw z4505#m{QSz+A_^m+^1CLIka)DaB5SMv_cCCaIQ7Q`>-=r3l0^7o+CQ=Pl+Wu0IwDl z$d09B>@7LjRV7a>eWUFKkaf7Fe9Y!P#-$MvI>@)co6*fjh6~E;-qD)eYz65SvnZA*8+poC4v0tbqS5U^)sNz_W5gdwuz{&@9Z2*Ms`r z_q7i;e+>Crup%N?@yVI$pUIL{-7R`7BU*a23hC`qg_L;#qaw!6^(l9+YN;(FA_b~P z_*qXOK&WsPnxUK8P;wm`J)k1{9Hb_?)qwQ=`EZ+XWHlh-)XVc^1W$;l! zf9HHxK=lcNrzpT+rF?rsM>)1ek)C+s!)$!xF&6y-V!vijbT_b=4yTC8Z#MN@tEW;i z-b?r%8p(D9~olT4G$jCZDW zv-k_Ot*ubdgW!W$MPCGc(1`zm58}i62$xMWwwa9NtJXBUKYhxgeNQ&nMk?yytyO7*4iZ)=!V ze;-+7-B~<1s)n?6yi&2x=rwMYg`vU4sJ@;gxreZqun#^*Ct0?x#Xd1MRzI+QhDCyq z1Ed~<he zk*<_<%_u_KT;*lal5{c6D^uLFr51N>>FIgldM#N7m0;0US%Y0Y-A7Ey5&J&7*4|1I z`~JKZlcH*SLZ8MpFm20k^J>n+kgrgYLgG_B=$SpD#q|7?Suu21xD+M#Q@IME2car* zgzVM}21{{)d{j?k5a-AWCRwik*_&a}gXB1kP#Hc+Zm26-;nlpscXcon4#QttUa%tE z?8|I#CicTPSnew&!Ku1d^42)|d4sjii`NX!zh!E!3i7U17hl3jtsz=(2%+ye3g zk1tqc(pJe!gxds4ChrmY2noVngc|+!Uh)RDw8E+A6=&oU`F0@u)y7oSadCT^?<*IA zDbTz6Vbdzu!8I%AGY?M(x3hWpI5@{ND5Z_MhE2U?E--YM);oiUiMmkH z7y`n9#D&pB6B2wyQ==RI2NT(to3N0D3ln2>r5ocpL%>HD-<`>?x)?QJP;_^ zfWIH_oR_6nd{tJ{h%ijv)W)T8Oqv%&Q_uL2TUhiR+Qd}hQ|T0|N?~}5UZl2g%gT+V z$GM#qhJxFHbQ!tiQ9=u$6@CVWS*lUW5ZlY9 zVJS9V*-Y6*gi1m=p#ykrNFN|GL+B@Pf{$Pm48k;_fo6dhwXMNHT4(ec~3+(Fbo4Kk}}ZP!{rO2fZmFSl`k%iJm@xXRe>Sc*cF3+il0iH!q~xpazkEne@9!`VEAlmbYtc>N`x|( diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-39.pyc index 55094ab1763ed1cc1f788fa5830452c79739ef4d..173351ae9a095440b481b1c5c9b2e270447627db 100644 GIT binary patch delta 96 zcmZ3&wvLTEk(ZZ?0SL0C=WXQfVpOQt&&bbB)z2=nsFIZl)~gHCYj0kOq`5SlNU0{au=rnl@~Ds%>nV%8E;KK$rKF$kf$D6 delta 87 zcmZ3-wuFs4k(ZZ?0SJDaFW$)A#VA&)pPQPJnW*oPSd`*Ylv$RlA5fW5GI=ZGGR9kz kW0=&KZYfTVWs;e^fQbvr90Jf(aj{pDw diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/base.cpython-39.pyc index 039416108ca991643a239324634a4c2661b6709c..1f8c82663fd76d0ed39a45673d7a96f29528f861 100644 GIT binary patch delta 64 zcmcc4_mGb}k(ZZ?0SL0C=WXOZz^qWMpOK%Ns-InySzMBzmReM-?~RR-&&bbB)z2=<^Rx diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-39.pyc index 35e8eadcc936e6cb34c528a9904388e4e8f12214..11681afeae27d2ea67d3086d36af6c16b88d9e8b 100644 GIT binary patch delta 144 zcmZ3ZvQ33Mk(ZZ?0SL0C=WXP!VOFTo&&bbB)z2=78S uD6=`8cOfHV)MQTnGDhpk4g6+o)#*f0G6 delta 134 zcmdm{vPOkFk(ZZ?0SJDaFW$&q!z@;$pPQPJnW*oPSd`*Ylv$RlA5fW5vUxdkH6vrx zWM$TH##@`KSqs=Dqr?hQi*hqd;(^Lb5|eUL2Qk(ZZ?0SL0C=WXPUWmc%s&&bbB)z2=$ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/index/__pycache__/collector.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/index/__pycache__/collector.cpython-39.pyc index 8f5760153ba6a1131af4ffd13863f54df20ad55a..9f371841e18047329b37519e6fafab455b775cd1 100644 GIT binary patch delta 3515 zcmZu!Yiv}<6=rPjdhPXN{loziKk(XKzp)KA#wHMAOd*&M+yqv%o9nw{?}qigo4MCu z8)M_X)Cff-Or<1HfvH**S89Q5N>tiPX-S``Ren^8bfs2R`>*}eA1Oatsp|RW8vEMn zO8f1Z^O`ef&YYQjd;Z3JP%A9V-$I{r+i%_vKK8Mw{M6SS-btK)&vYitDc*TbBrV&V z;KJ&B!PKXxxM5qJ=~+7=8~h6_EN|zP%MbkzdYi~bG!sO!og9m&Cd3+Ng*kb#n4Z!s zD;5)QE*b!>@^y=xb#W1ej>dv<50!Ukwy$0Z?#q z1%G3jTejn$;&#G}N3ujOgen;2(Vbt;ef zH2)=5;7izc+H!L6BaPs$dg#%RYjIHyyFr3TK3U;w$*P6;R z0|l3|wnAyHc!b+_(wMAGYm>Y-Y>7VkhoY8PKb+-@3iv4@Z~_y_6gRXfE{#an0i5494DhPL;K>v+{D;d;aGkIwWh#D??w{ ztTkL7W}3X*Q!W?Ff3`aboaDKIRymWPdVbX%}zu`xFk-@x!mRh^WpBp zkw~@}k#{P7QMiY=luQVPCNESTZyN#038MLWifcw}V%pFhAFbK8qJ@gZ<1u$A|5;hS zVHb#UV0Yi zBq_L+ z#BYwj&UKp#&@@xxt7PqDCkN_C=3B=9pj-+m$jER++<7T}46%>0gYgI8ybrOW>A?egr51a)V17eRS< zqpN;^T~{TuSbvl)$lulP3cU-Z_W;UzDHGiJkUh7VOY(@%-QNEr@=gLztuiOv%)X{l zyj-0pkA{ou+zoPjo|@_F(DX((7w$a1u~wYiSS)Vpv6$l zOiIKnko5ypF{zYbQEO%pDJ!q{D@|>Mw_Pn2!~V?2O(ofWTw8Om$)VO~WQ%3y^ceWECY%F#ei;kt1U8$b*S?~E!tfS7>F^N ze_pp@7PTR|_Ueh@u$bFBai2Nad`1^4``*-4wqIm-SDRU$yxTq=^i+bZ?r3OQ*H)Bj z3irt24;VFt93t{rh>3fv)t#65O2-k#_RHUQ4tKAX-j7I0-SMnJQdruvr~l?oN12>hSJ%x{iaIA1geL+henjvH$w1Dx6cn+1 zmc!&|&n|TkTUI-yyIvK><^xDp;=cT(=T0*!l9q879IS|}#AB#F)bi*`wy1_V{6*!#J>}sa6Xj&5OnoIwz=!AdP`mJu zc%R9RzAAZb&rI#FX*4Q+1HIn@9s^V?uCi?DGq#};DOly1ZF~m3-?zkmDtr5DeMn|h zp6Rdmt2CUDOa1jD3AjrF>Hz9os2xL%iK_(EX;l(_35Hs8Nz#b(nHXK^G0U75I=7(PX6acMo+vveCXh*VKD(Em0S~)4VVX90=xsb4p1pw26Y>t b&VtG-^5)6tS_wLV!6`F7o#Jw7=<5Ffbq^a= delta 3422 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 delta 4519 zcmaJ_dvKK170=x~*t|#}BufGbF%V!0Nq96*LeLP%14ww-5ajW(+5NKl$iBSaE*RP& zK`mMZ6z=q8wL+NO{ST;Z;)fan*pl;Er8VkCt%@isE;<~ElguF zy0>6AW3A$qS#<^XKw3&5GX{g)?+WuKkx}T(SOb2Ws4Hw>b;4iR*VO=>ywHfYU+1O~ z3}{Ax4DNt3&Au}S0PDU>d*!h=;GJdhi;>Nyj4AD1PQBVNJrdr7-$|BR?&}4_VjAx!)tF&&_?C z^@=Z*7LWSCRU+g`&Z0HChjdd5axDw+*G<#q)f0k5e9~cQYLS4;Coa#;5%bFW*df}zS>jxIW>l1USk+

hsbI?&6-pt=RvpuH)$QbUHp5#a2$a?v-IQh)Qi&#o+$Y$tiA$xEXiJUS9atl z2Q5xl7A#N!r$YU4z|qNuR{YUxl}A{)I@szsk3k8^k(p*lcN>F-&bdE&Xwha{iPG8& zh2wxRfXbs^{LNX`yp6_AyG(WaOsi5RJG6|{`Pd7~#1-DXWaIzy{@I#}=%ppI84HR( zSIwqF_es^8D^&s9Ii#d1Fl-l}Ep25!5nNv=mTtD6xv!cP1W6#-{z=jJYeZ9k_~SOd z0(K}cqAgW-qAH~K6I^CQa3T(_5w~g^M5uPh@@FADMKI2!Jyy%6WvtF_R*TOt!|tFz z)OuB!i%)7hlZuE;Q-}2tr=5Qd-o8aZ?L$=uKLpO#0pCTf~gUQuef{Z7kf^3&uAH zWadD`@OiYb%gYTg2f)nm@?a!n%2b2;!hW#TI=ew(Gn~2B%Fr@o)_#}IP##Q~ZAL;N zEI$zO^RtkOA2iPH)j*|&xM8`^zdffGn<#(CWojxzxc`)jwCl7{z9~{ zsghMck3eiP)$e+MzW_ScUR0$g7rF2@zgu;?{7Lmivf$?c3jmJ*5-TFK%J=!A{%}<} z8y2}OrMpf*KMjDJ&1y}vK*6spSnCRS438_UZ=+-w0q+KVM8%je<15gP&!{NuIX@cu*lVXL9dt63=Pvc&DzOdKpwwOp~+tZ#BbK@c!=%d>9$o4*vLG(m}v^!lh*t# z;)nee(fqY9ve7X(K!c)6P|l{B1rtyd#n4qN90R4=n!4ImC`u`vKM9d?atV}*S2>R7 zQKb;Ov(F}4)-|U+N~HMvx{{?CM0`1AU&^)=j^5&AR!)+;If;0SIKOUdZL9-bB#z86 zbr*LJX{I|E(m!_tz~+j$XMHuhLS?#gAuRc20;kQ&?iDbSV!R?Qt*@(Aq1d>ZBx}$J z#I|M1DP9*#I(nDKEZ|aRk%9hz7U9(Kr&`Dxr1X@i=_nDeb#&O3Wg5RI3Ob!^tytYz zOr3mtr(4BK{q>iKQYC&WUx&r@&ViCQp)-Y87Kdh6u?rvPDu9`bN{^$f{!_Nh=bVISD5o8+xMWRZ=N$&tLBd@?Z z#cD6=qX#$aVhd4BGS%hr@QqMDKrqp{uR)YXFFI3-PdAoPy5?-^VY~4V6Qi5@mi-C_ zH2^#c`5y=-x)3@r-wjCE_h@=g4{HUthxE2Ws`OM(O|zbX?}DpZ2^Q>3w@%P|6S`8I z=q;x}&h}~d3CYIresS`PCl<#% zP<{Dgf$)D!sl1`jKmXJelIMuGGL`(PCq|tZ>%U8U+P5^fgZR#w{P!@qDC)L5*$ts> zugq2{LSp#1cw+m??zJG*`Bll85$ns;gk!d>)smf#ekADp*yot8uwl|0+@lSQ@JwjbiE&rO7u1734`%8qrON*(hSLe0nO4!JK|dXU z38c8?ax^NpGmL;4rsod1jXg|x7OBbU1N4bT`G^S<0~I|3KOIf}%D{v(0mT6Ik(3Tf zJrYJiwF7<*m<_eFrXTb`$hhzpn4Qbp(y*TDwZga5c zd9TLWx=7eVXVC$R&spbA{3<|u#KY<}oahOT`-ICVo!3XCldX4dw!UDoX8tkYzW_r# zWBkOH$)bJxbVfgjygdA}xH()Tj{Byo|7U#-y4vj;X#WU+4UzUXJlF4~*ZQmAsV#2+ dr8eLYD7Eh@X)1@6;HkABqJ&suiRF=G diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/index/__pycache__/sources.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/index/__pycache__/sources.cpython-39.pyc index cc57eecbe723d74ff7d4158e3e31053a9edcfb39..337c772edc24c44de52a86bd4f8278d743c4df67 100644 GIT binary patch delta 65 zcmZ2rvC4uwk(ZZ?0SL0C=WXQP%cM}IpOK%Ns-InySzMBzmReM-?~DLT#Z23Utg`h{%^4v=Uer!Lri*&~afH+G#sl0*xO; zU3Xm{)OZt3Hf9s|ZGBiZjSoJXY~o*FGW(*w8J~170>4t^_BXAcx;cT~aTkY1VC1jYM~iw{9xV~YF!j7ljL~^LTP@3) zX^d8CW|0ngZgM>R%JVT7rzx-U#FMa!!~q0u7d!UQ&QEY@GM3GCwl0c z{vP^|ztb}fuh|xQFV;&(120bqftrd(L+3Hoi|3^!B% zB@lGP*yhhdP@ydctW-@!HIitNvp7iGg5!J=Q}EcSL%!(EW-Vv7e3Xvu;1oAkzZ0Bx z0PPRj6TQ#iQm)c;C_E3Dq><3x{?lk;N{}scbe81WUCwd?(?#QuV&)ET4gP3Mu*O!kYau9pl^RZ4U!)J=ywI=M8R>A2M| z_*dpHFRW#jR@0VG+EVhWR4@pKyLiY7{k@}a3W*>K0G3mgHQq&5!4~{#ZU?la=o-0z zbFPX+%%;r~bfGiZc?qU?m*v#eoaNNyU9w2u>-;Tw8HULfghc?suNX#E7OODp8Zl z^05RgpJM1O7&R|fzo1Aww(IN(FuNw#qu`!*P&qC7hW-bppR@=sgZ_ z*CDj#O%aM{Gmh$I!XlGkt%6#}i}i!>SIFa@&k{kv!U)2#sPsqKb)12<=Kl zQ?y5wF~|h?3vM`oxFfhhhwwOUl$45y%!)=u&MJ~BW+g)w=oirm*!IV04Dey}TnII1 z7v4ZCQGcmV;xa;DOVJK*HiF0IeWV@dPb2Iiv>|LD>><<;P!`b3O#4i|j7ytP%Eeye zHtBjS9BPc(Q}yeyeMb)x1;x3Jff^nO8XcJBZqRgpAKf2ZrS}JtOL$G#S^4d(9>;-3 zRyXkVgw)8p$79b9e!s-D!_IgZt@r;%TZ(@a#mqsW?_-Rc$G7`4KH&Snc1Y3wp`W?+ zPlkK?G)SBFXRI1ZzMKYaqdgC9hP8d}u-22|iSVJ;p2?^Pq5!e(W$5 z{cQMRXcjG2NOmEv(7%UyP{_~-<*w21MlP_s#PZ78jzXY8op3E%?)ineON;j1;=S_1 zT6!tHX!lk>M6;am!Liy!QPMQsluWow4N)X-;YN5s%eAHJDq($t-&xDAk}8N4nwLzY w6Y9ZkA?TP)i`_g-W~^aYeUSzdL14n{L5o$NDS{P}@yKXxh>BSW`XKT7zsE`SGXMYp delta 2094 zcmbVN&2Jk;6leYYfg2}j+N5@6luvJHY-mW+lAus%6E{d{NE%W>(Pr(PX17`IZfDm{ z+)F@$A|xaVBOw%M`8W~51^EJ8IP?#o61NdT>Y)d|P8>jh5bw=ajT7ZWr2O{Hn>TOX z$M20_UHoGqsisnihv4te@7ynw?}a7KJ`L-cJZS#9TC5VyP>Us%YG)5^fW42 zcWP8Fq7?B1h3L@Q-wjr(yOZ})p zf@phAr53Uh$h;Qx2{hl+~&(-HPVI@>h?nilWR<5Fg+_AzOhJ=?wo zVf@&hm6q7w?MKHk4>||HgC?=$5WR?U+|=rXx`u7h7jYeORO+?3l-c=?LdObh$sr!J zO^pXFvQFpO+a13YR8Z40!aM+v8?IX;N{yO4S|zTlu997zKIz^>VE*wdU^TrR;-Q*LC=Ve`c!=7zM@x7s1HF8<4nVtgO@=Ke?U7va&otI#>*o+*RkRk@|tg)HQ zsfchPbm5Ob7WW#gm zINlwGe3d#613%$&$XzoWh{b6ru0tw@YAO}gC7gYp9fR84&E^25qtj{RqTl>iP?DR= zM^$N&C(4F(|9PTVB{@dhaQ_g(>j(!Bkel>6!W#&f1&pYe3BhVndcXcGnR{s%Q-hWY zR~e9b)U8m%fgE-$ee>px+-Be~)*AYI6Fw~#G8^oDO1j0&K9k+)Eu0&{Z4qVMcYOpE zJ5k=ks|`yofBSo5 zpZEqPmLIsgi7{MD`%f>?MjV(n(L6OyTRc|3wt+w&WDbMRvNEP51e7tiVv3lGV_r{WNkK47TU(dE+%bLZw}=p{Cp&uzYi?l1=)D%-Y6#pvM=D7??K2E>Jt yp_6EYeDJ4G4BZMY1@m;2M2j&|irn(KdKe`^06_}TOHnCNI8py(YZvb2Kl~3}Uj9`8 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-39.pyc index 4a60ed414a0221945a1484181b40a5d8f5a13583..326727db979c5a3b49e2e1534dc8c0d1a3631162 100644 GIT binary patch delta 608 zcmY+AJx|+E6oxUuPKxE&8CoF$t%zuX2QZX@r9vs7qL!485lhH&VyC%^<7>{nL1pOB zwM&OPw^F5|&Zxhj3{?kyfw%sR4yflONNMiy=zQsYU)`JK+hsGftl24iz4o9n{eQY=rNyRLC$%f`N#k6(SaBx2OuGeH1$=x%0l2 zg|Zu@Jcxi@#6a;zsH#t;4_f0#<-yOwbC<>|gjGad6m4Lc6zCYr(A8mb4=?C)2jNab zLzOMp*`~?=;`^4X?W%L@GX}BCd&YgT)AHiRGqNz^clbFXFJ(z6I~@8bHHQn|Xt6ZN zE+@pkmp!eiUfXL*x96O(&9JJfReM1@!u9&r8;YS%W*Hrkr%4}6ehF)R#etYcOlfee zuI;9FsP61X=2*O{o;Wq_M7?xskB8}B;jwQ;7<(XDBG%gd2uQ(KADu0Ib6EXyes8a1 hl^2ABe5S>D0uAh8m(U~}5snEbgt6f$sJg9O`~%vom9qc< delta 592 zcmZ9HJx?1!5QaI-aSqm=FH(?*Fd%G;XcL8NBA`g1K@fur5JY@Rr!#kflg=NST_agk z{D!5WFdZ!tqNJmuKnfMbcGUa=8|cCB`JcGV44Q^k z3>t%gD5yT5%1<{>%^-IdmXR8Qs&Ze8^MMGjhDkiRUB+_wVcoi&!{sD>;; zJ5fzYKaRbo2%+L5MrbywSb7nc|D^e_W({8+c(uA0kOz=;2L*MSJ~m2fgcYymKD1Lm zztQL`!9{3G>_OC!LiYu}^tlP|=deVZ%Lv{JB{jsjvp}7<2CIx4Wp%{b80ND*U+ko# zh%~(_=YlJgRo85A?y;m MhDlXW4<8R-0eHER>i_@% diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-39.pyc index e6b436df66ce63668b97e6b7cc12f27631493e62..988818c0dc966c5a7a2072564e0f96989c114975 100644 GIT binary patch delta 548 zcmYk2yGsK>5XRk0JTdWn#LFdKj9x&3@pVQ8-!BjXf`u`$@PR}eA(>7Vg4?z;Z3r_F##^Z%5t<26#2twdSoFwZAIUImdSdz{$ti^0 zkTz2LXo^o$Y6cNexInsxpb=Df^IUZGldL^WYJf0EpjS8Gq`f;5Ce=uvvT{4eWj>0r z?J$k9U4N9yl#Hskh`>Ye(w=225S1_4G(5|yI8TEX;7cB7aZJmwEi}TISC+`+y} z2s?LY=?^g7m=Ja(gkM11l3_ty@E_{VbJ~Qvc=F!&oO|zk&&lk+nWUwviAS{Bf4s9~ zJ+6CZO_r;cxo$!E15}&REC#lJ{xg0R5g~p`*dmMVSo>JnSa1Vaaf^#miw$l`74$LLFz-6X7DF_jyb$m8`uO%ySwrExPI*$Obm_IkAT=edPH^^1~j-tyHSV707Tu=Ykcy)4z!VejZ$#T4y88jnOZz>p(xt mi01=jxzZV0XMFGQdho??kSq^a7MJ9wr4|+IyW}UA=BDPA6zdmM zmSk+UU}|AxjGDZc*@;nn5{n0r>B*AHC_8yQiz2Ty(4bpvC6xu4dFi(%-({K1C_cH6 WRgzI+ayP3Mn-oyCNOtmWRv!R^b0cT~ delta 113 zcmbQp)6T=4$ji&c00ckI7jNViXA;ZR&rMCqOw{*CEJ|@H$}CIO52(y2+3dvB!pL}Q z@^NM-Mv2K>EFM61FiR?<{N$Z1ioCKw{kPakDho36(xWCnXPFFCQ_U*LC^>m5s}`FK MP_{^Z@=;bF0A=JL(*OVf diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-39.pyc index 03131c0fe35db62a6973fb906ea377d8d089ab7c..efa3a9ec9e002271ed34bd457d8f99bd9a1107ca 100644 GIT binary patch delta 100 zcmeC;pTf_b$ji&c00i06^EPrnVN$5l&&bbB)z2=3Qamcxv4;y{g2Txmu5x$)&0si`@d%tfL=p&~I5AwKy&+iCy|GaiKi delta 90 zcmbQj-^I_J$ji&c00ckI7jNW#!X#FppPQPJnW*oPSd`*Ylv$RlA5fW5vYDUx2P5OH o%^a+U8RaB^%5QO{73Jr~muIA==4dh(i2;R*#6g6_@wn1p%!=twdAnvTaH!nO#u~HJ(gJ zJV+*9NYI#=7(Eztqel~NUJZ#cYvR#^2V?vToM#K^#XbD?+4pnio!KwacgdM?xf}=h zQ#kVMopaq3SP^rjq9hh*UQtU65>>>pQua7&+wAcKzGrbk*pBCk)gAgTN5b z%@MZHR_J3Kx>;G4vUFJcbXX>2mfiF=X~WGLarYsjA26T(f&E{wf-;U(O^vtEiXgrnJ zn*w{@*2qWwp>4}VMp>%;t<~5|j_vq8jsnl=CcM`odlWunqeb+sy2O1~+-hvQ>glO? zeuWch^rbnD*M#1N4gf&_<$H}tF2aP~!pl}UjVuC;cnN9&kU4ZAuU1MdvGtD4k*jdj z0CvDQ||Poc6KPOo$4TN8#RnzB&cR;2?H^ zD%#Jklf=4$w7aY|a+F67MdI#N7%EmMBi(n8%fbD0J8_#REZL2^CiXS*w7$$g!luez zMP!vRak9!b#B}}rinCg>j9V@6%HC-5zwOu)(L6L(ZRa)9H57^JF5}8YihGysGJ2ij z&~1w)S~r)R|Jh#j%o3gb?Fn(+*xS{YLTHUFsZ%^!qVza|jUULk)y4?t SV8ghKEz&hUJ|BDBoA?J7+~&Ff delta 1036 zcmZvbO-vI(7>1qgFD)hfRA{h)LNuW*u%%kd0WpPEKtK@GR0O24>$1{<&NdJP(;oF^ zGDjmPjWHUdSuZ9g;?0AJ(Tipco;(|m#*_07G<&g!r{BKc-^_e7-<8jbH|O(t4)Ncg zPx>qGJzH}@E-HB~Cy(Z6K25cCMV{VVE*Y+;U-~w<~q7(JQ z5@U71iU2yBas)`0-Hj$m*4T~O3E6@({N~*NxxZ$BB0nX}19x7f+%a zY@|0;zYWFm?HAeN;y|^Co7CIr7Tb;b+1K8k#tQcx3`PuzRxk##%^t{ejd%8)R=rBK zS1302-(IOQPf1(7n(Y)yIA;39-RvzM+{#N_r2`zMtFWf3+Nw&IAZ@ZQv2XnCJ?op6 z=7KB~_tz<^dbOafuF%5>XYKLs6Bl9Cs7h&q=PHyQL#lXP;xULb%|gTZQS6_VSvfxc E55|1vf&c&j diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-39.pyc index 3d5502ab8aafae21be5a5b3f7eb6fde0a122a7a1..ba2a2c1830e1345d5361a37a79205b3a6ec7bf6c 100644 GIT binary patch delta 574 zcmX}oPbdUY90zc3&Ccwu#-ClYs}+$0D~wGn5|NbH14=Dfb~TF_v%MLz2Sk$lyW^r9 zT(mB7adK8}b8w?vCY1Kt;oo7pp1W;_2;)0-=3yJb=}Z4 zb(3zGmXXt_sg4_~JG!=QnQFdZtrtV(wujj4(|b!g*rgcdK8RToXQN7p#ib)RJxQlZ zoS#dZ{%J-^u#7M5_PqG^+_daB-SqB1DW&2;;LPI|qw*C=vPW6r;+hZH5|cQsbn9;A z@uA9>wl7bOyhg18m9X0ZdH_bGy+8p8(9f}jtYK`?L9BSmETQaEttpilZ*R1jH|VK|UfXjh9`1QikOiq0Qs z8STV~+Vu}=Ewl+*7qto6bl=f|`|zA|&%O7Y`LsT)x|FKc)`;)-C10%jmco11j-Ae= ztjQElkMYdDZOt8S7D~;ovcy*C*HdI2bSF1?I>ebM#neW6m&aM0f~rmf-jk}mde4Ow zWu5iXmXfSy-;{%@WqkRnefiERR=TLYkQ{w9XT{}Zh1ofcesue~GbWOi6!%Hn%0Rbg8t^Xt0fSI=vnRkK|4iuQ{QvS!}2@s!cHs z{Y2fBxgx0OrW+$d5Bj~FLbyUX<5m3d;n4m_5{W3V02sh3;0)@4wE*jY1~^xwVQ#>t vD}SUlAru?=fPlg@m&5{MHMxv>!{iByheK?UCc;mw=i0nw3314zXVdxz+fjRl diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/__init__.cpython-39.pyc index 01479561722e0d4c6428510027205f326beff0dc..2b946f8099a07005efe1d7130b627410ffca127f 100644 GIT binary patch delta 55 zcmeBWn$Elaj( JWK3L`0|2f<5?25K delta 45 zcmbQv)XT)3$ji&c00ckI7f<;4q diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-39.pyc index 197991e81083251024cb605b2e64d15d537a3141..2a8659907158c0fbfbbc750a773eeec17316aa62 100644 GIT binary patch delta 248 zcmX?Qam9i=k(ZZ?0SL0C=WXPk!K6^7pOK%Ns-InySzMBzmReM-?~(dsizVMU1%X643X1Xz zQj1C|i()}~5Ai@JgWKF&(l^_8&oT(`F7EftWPEKZ$ RUO{3}acWWUW>0BGMgU0vNaz3n delta 224 zcmca&ams=_k(ZZ?0SJDaFW$&KgGsDFKQ}ccGg03ou_(o*D6=e8KcF(BWbogeQNN@{j=A!c>%ci>I_GCnqyWuOP9gIJGEbbFefcBLG1pK%oEt diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/format_control.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/format_control.cpython-39.pyc index f60e6d77a3ce7846c56360f5a0cdcc64b5c5cdf5..7aa1cc3bf18bcb98a28122b385f3bbe6c35c61f2 100644 GIT binary patch delta 58 zcmZ21x>l4sk(ZZ?0SL0C=WXPUWm2fq&&bbB)z2=0dZ~y=R delta 48 zcmZ20x>%Guk(ZZ?0SJDaFW$%<%OqB!pPQPJnW*oPSd`*Ylv$RlA5fW5vblpvl>-1+ C&<_6q diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/index.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/index.cpython-39.pyc index b1869bcbae8352f8ba125021852102d9ddaf3086..eaa3d6105a7ac44febd09624d3cc0b1f6198fe59 100644 GIT binary patch delta 64 zcmcc4`H+)4k(ZZ?0SL0C=WXP6XHqED&&bbB)z2=$cZz?Dl`rkzP#6EB)qo(YEtE+c+bndK1fgg?f)+?!>}BDmHzcS>7Qqqb5bJRb zwhFJAv;l-hz-2%M02$De9JjMKuCdw+-0aV!POv%vmjL3@MMy!`TC_-lY_I6K)CGme zq@4{E?~`u!yZ8gg_wHKP5Nuw+HNY^h%FW!K*C!i(dTvYI;7z5;9!5({Uk{Fi!!L5h z?>LqaJlmOOGOk;qV{Uf3bUI5Uga*3VcIjl@VHa+Jn_-xu3OiFb=X6Rt;WbMl3l2qa!fH}G7n&^X>)1kcR>4Z3v?FtKDvJ%mR8)&Nm3)JQEMZ$ zL|0)DB_5j*blCtgTv6%(KiU~ov$Itrk<{ZF9Ry(%5CMz<&T+6E3x>XA7s(S-k;v%y zWN(igW+RnZ?bpFT{;5iCKtji<0+TxONszZJTIl11NY{ zyzvS(HF?>jVdiY~cUZ6>OFKuVS~9Mvn()fs)IFF)7!mv^Olr29EZNviw%Du2anIor zZSf0y37+8Iw%D*1UlrM5Lq4x0Ln$8UGE4e8Gon?jw#mcZ`eyjT)-+i`(Y}XZiImDA bAukHAyft)1Ru#U*)PQma&@5tnYzqAae4rYX delta 1163 zcmZuxO-~b16m=TP*H9=>pcILrw1ox*6H)~P34#cy$cIr}U>&AoJ2>q$Zwgw7BqkCP z6GHSRx-c$Sxo}0g_ZLXixN;I>T$re9O^gfmomU`4nZ=ni=YG8V?!E2i#FGhGak)wl z@#p7jYfEmGYv((XT1;0uMidqsV)~-iF_BGVa?|oTNwVo_*%v92yYH%$%DQ=wU64|e z8tbFY@;g;0xe#_RH-E7sfC#l!M8i9BJ=_Z|HKFl<2+T+K;278-N4%ZgO9M%?G#$7^hOtoBzdc9!nmA{Yu^`QL`303o3E=CH033_7#C_ zw$n-*dWM%#Q#)TM3W(5ZZQQ?e<0yO_rX?!2ow^m%89RfF5h|}s?lylIN=aT`ue;l6 zSEluJdsI(lG?r3~_C?iVF_>|JEh~l*&5y+5lMBNTqdxDfOPngP#(bvdUS(IgCX`%F zy(GyxxDaNj$#=MB9^d~=)u1Wgn%W7=2@ZB~nwe>hWwQAd8Gu1tV_(mq6#>Ms#FfSn z>tLE)q?*aJZfNX093}vhfGO&2@ONDWodJllX2H-oHV04vaXSq^a7MJ9wr4|+IyW}UA=BDPA6zdmM MmSk*R&E&%f0P}?s?*IS* delta 48 zcmZqV_|DFq$ji&c00ckI7jNY5ViL>I&rMCqOw{*CEJ|@H$}CIO52(y2*}Rp>hYq15)C7^&NV-Y)$TFG>aNzdRGb7@fyLt=`H&`CF_&2c#B9 z2^XcNBqo=nro;o?mRb=HR9{@A4pa~&geh~2r2x&m%~~8?jEw4&w{m7M>Q9#AQWFR1 zy~Ui9pA2+}F^~;);N)nonKB3ms{&b82Puw7Ru%aTR&4sKB z8I@Fk0-B6P>_BQI(=8@FgImm{ML7^9V8u$4P1v`psRHG1u>!44ExsjOl$w&5T#}j+ z4|Gv#MLbY_agioS!DN08DHJPAIJy`aH7D=q%wRN}tih!w4pzpTlb;N<(;TP;>Xyl= zTr&+3Zc_)!02SCG6o5?UvdPITE=kVMEwF0@$!Jg3=k`$qxeQ^HCKE&#*lZ<`E{Vww z+!B+wa5re$gH$Sm2sIF41|l3l1j1sdk7Ie<7%e9+;n^M-8gJe#$Mkx^|kANzhLV@;r8nvAztGxJhXD~hy% zyp@bahCr%F7(~c`2wfmy3u5R2i7KthgN&f*NfB7l0T&`30||j0sRslNre%geuF;u6zQFLLjSdab*^#WEN-TXXcd@ znN3dTZ?V(@nWh0ESU`jUh+qX0x0pd{%t2fx5Mc!(m_ZUON%{FXMK+UF1YFr1K%$P5 O^97_Bqb7F=lmY;}OHjH1 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/__init__.cpython-39.pyc index bffd9668801f6416791d293cf0efa6d9cfdb0d47..2ffaee296356c31f32d3b3fbd3e336ad3b4f1ec7 100644 GIT binary patch delta 55 zcmZo<>Sp3jJ@^e%5vx_o|OY+lFi;DGK@{>z*Q}arS^$RLX JGA2&R1pud85+?uv delta 45 zcmeBXYGmS0Rqizjjyi{j>U$&>rMMJjmZjbry`Zq_Zt%jIsCm9y<-#k>yX9bmJHA(_ zKk`?p7h+(R>Ur0AioKdBTfyT%74;mY$JMnDJgu5$*WPyy<1+Uh& z4#mEXZ);HM_2kHs6|XrJzGc^(swt)ZV}j1?)GI-ggATt&31u%Fi&Pxn*vY@B90()1b$~E3}?Xdj88YfYH3gvrc!t+ah;Mrxj!o?8X z?jGn<R$)1IUZHNVW-hGi>qp#hI2_<#|-kTKb$z(C0b=={bw%}g9wKv2}(|nI) zi1(0oaV$)||Cj6yC$Lh~>ts-Wq$L`q?icbzHr5!sGt_WsCkWTgJj~ zo7erC>zMkH$})l{;2jlMp}T!Acox#<0QF6#V5yZvVHJTGFaxMHEx^J{6B;lLECVaR z!4%3GfGY9(9i%l%w&$$;O9k=thk3?-hF50c|YczuepO<*osC&ZSwnh z=)4bq(TU*S^ve@MFELtXgK|N%)7{d$Hg-nZzc#ZEXxX;1a~3NXnY~T3OAj~dyy$yN zM%?edJ>t*EZETF!0_S_0CjN1@iDCCcU|%C+d^wa#kHeji5TqgeHAdI%-GBDJ4((}^ zlh_poMkI_brjAX)aS^x#C>4K&*0-u9!EZz}^CDzd%5>MXE9+H3Owrr?ZLlq~;ZSDQ zEXUcYva$%tQ>` zk!a#1zc(<--5~ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/cache.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/cache.cpython-39.pyc index f5c86232bcb66ef9e0eaf597d366bde65670391d..d36d5099cdf99e4915822c46cf93d18f76330936 100644 GIT binary patch delta 70 zcmcaCc2|r$k(ZZ?0SL0C=WXOZ!>CZEpOK%Ns-InySzMBzmReM-?~*@`lc#d+0{|Ja7+C-S delta 60 zcmcaBc3F%&k(ZZ?0SJDaFW$&~hEXg>KQ}ccGg03ou_(o*D6=e8KcF(BWb=2%Mh?bX PlPkGY8KWl8=h_DVTci~H diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/download.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/download.cpython-39.pyc index 0ee920a855f62fe9be294a9056a0b2ef0d5424c2..bec9680b2587c03201fb992f60a39ab4f4b20160 100644 GIT binary patch delta 828 zcmZ9K%Wo1<6vlgbj=1w$tC_Wb4=Z)^?Zo99tg@otFDF_&lH*u};6)ooT2=XL#EB4<|DQ0#tN2oQN&d86jvp7l;uTgFtBHEV&p0V2}Q)m;%CTUsfCvw@?QGx*`pFatOmc`e@J8VT*TH(|x@~;E8fXNXuP!;h> zn`dk8ckL>Bb_bEWz&!wejP6Th6Z>8{0=`$@wclI=F~7MFpk{!Fz$0J-IB=yYV{hcL z&q$1g6lq#xN%@EmM;7u`8KW9d2NHk<_#Fs99caTMHDq*GE*mo(wc(J$(trKEY~G8S zW}|PJCS5>8(fumBWz zSx-;rV9rU%W5!^g0F-o|@9LYZ$iM6N*m=HX%ucC&F$m(=5u&AkI|P4eTn;bGY4!Q& zBoCS^hFY6};3#h;a{QS&%a;5P<~tU2y+;V2;J>?ZL;88kr1Iy z*KLdNBl7z0{}fUNtwEwfUWbJY1anpVLfiJ5ZrABID8v86-zLgXpbHcND*WTfvB{D& zAIs6hf))%g`TjCBD)Fx)PuLY1`P|8?kY586S#w+z+(@hYD2%ttx&SK2`B8SQ)?u?f?#O;K~Yrabz`9#Yzou0Tb8;RH6Y`2eK{H zrE^z~9{M-T_OQm1zX@xpjELHHty8saIw$9J23Q1gerv4F7S*Mv;TQ*|0bDA=l|kR_ Z?e`47B^3bGSJh_}n(DIV6FfIw`U?i!rKJD> diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-39.pyc index 78c28886f6042b0426b0584465f2c269ec2c7a1b..2fd58fbce0d2513c419b1d190b2e034b3fd9b373 100644 GIT binary patch delta 437 zcmX@=c;1mak(ZZ?0SL0C=WXQv%%o7QpOK%Ns-InySzMBzmReM-?~13o|5PR^AE3q}Ul1V+C*(jZzs<)4&oeOwPM#)`#27I7r-+Pb5L^XV zEm&FbWG&HOjDDL{#UdCPLnqgXOEG#(o+%#4<^fV1G5Le|R>r8w%Ow1`Ap#)L$jSdD z;-LyQr%3uU$spw7Knmi4L=;<2aZYA(YSiTO(lEu7O=P}Cg@RPDfCy6%!3rWwKtu|N zhy@W6Ai@tsNP-A`5Mcx)Zn2gZWtOCBvKLu^gwSoB+$?*|!W$$5*6RXd@qh?p5aACZ z0zm`^hzJG|Y#;&@_(h?UC(20(fNkdm@xhL9n_RCTKKX)NG-JkQ9eEE%#>~m33IPBB C+hQ63 delta 429 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 J4R$KB{eN6Kd4K=_ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/utils.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/utils.cpython-39.pyc index ac67f31b6f6a01b0d020d6bfd2975207454faacc..c1f2b9cf06977242b41eeb5ce972fc1c2c71c578 100644 GIT binary patch delta 58 zcmbQuy_B0fk(ZZ?0SL0C=WXP^!lY29pOK%Ns-InySzMBzmReM-?~)^I delta 45 zcmcc4c$Senk(ZZ?0SJDaFP_M4BUYrJo0^iDsPBnHa~GJFC_$)`i{lg1(o&O4Qd5d7L6TM=LL5#=fLKnG3wY%johDD<{RXtUozK=W ziYox(woK;jl>W?pegVopwK z%B{(PJVt76K*16qE*1b146JO-9E>2y#wfwW!&C&41sdfEG)ijnVV*c0N00z(kv@jU$BpI;4WPW}<0Z>>JfqV~kH_#ei G{xkr0*=i90 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-39.pyc index 4783d062c372247d49eb03bb758c13e01caddf48..6028713f0bc2749faf3b18ce328f6203b6638b8e 100644 GIT binary patch delta 2917 zcmZ`*Yiv|S6z=q~+ivNLLTO8(LQ7!->=vYyhm?m!!>fRjBCB$}-M!tt*(Y;%3k9*_ zgBVam#|R=q6@@e=61~9)@$thLe;H%+*Zm`jfBa#h#E__o#`B%K-7Z9%^xK&;=bSn7 z%{gc8SMpm~t=H7}O6V^>`@)CSH!DO){Zg^BH&mk!Sy`!vvs%QovJ)k8De3%mBp6F4 zjbL1oEIn*UE7+e7=aNP$YXvi-*_euXPKcoT-E+miob>%=vYUS7G6JW1By4FzdN^*R zBJ9nDfcnzgDSFk<-Wz?Zp;whOlSXzlV_1$anlmg*!$huOe@?k&B!(pvS#pP?o0a>Q z^x`E$MV+kv{Ssn2$ zuSXEYj@4(rWn#eo)%S&H-vqldxf3e82pnPDq593VJ~3!dtC=Bo^Eti5a7NF@$YvjG zLa^~#aWj)KA`@kDFU>=BSzShrEb(R;DLrX~YV(4KDKU3<2&e3PuWcWD6uy|B z$KbGX($euxnjlbF4%p2a;WS;HGz>XNQ-3*cEFYn9VY7UsQiBnbyB{O)>NIGu*Q|6- zh7B#N_SSVwH)w$z@!jXyd$I174O^gJHEbpf4F{K7;e_d?d%)P$#b`TV2Vm+h1M2bm zrEO6X`aM&5C5!IJzFc2lI<^@ab&kihG)g(yOH-$gCdMJkS~C@;jFz%MlT%?@5X{GB z2wV=sz)J>*RAN6l08u504#o^4Av+=Cg#3>{T4)U+IOS|#9REP$dXchEHRgoJ-CtGB zYwmV5Kfh*g%di}wU*Cbto7NQEr*1M(;%+iX$+p|; zc*6wDeEAecGMI3TaNT5>X{4;2G_;s*O(r_DM%2YQ&8>xvSBA`~t2LT^Wg`4JQu?Q1BlsA7{>h?UF z$eWmd%iBY1d*lP^?T&@Bx#cjM&%i}_+!(dot2(28>R2&@y}t!#Ow%?Rh1BBCIe}2^ zke&_4w8@lanw&}$54waS@@c~K1niN{vm(IzoPaY<0Zv8c;5Eq5XXJAL4*tBlud8k2 zIL-ausWfrJU`L!^xS^1b56(|s@kP>-)2e>!YE^dE6XK*jW1(NnM?8KZ-^EXShFqqS#U1`<1 zCnJeG%GiYZv#Y@#^j{NWYv8QOO~TV~!CXycI&;OWrLg)E;25AEPy?6-co|S=-R@I! z5wakF+W;3ox`Mx|K=`_R^vnVGM_(cx))U-ioigK4*sZm4d~e)Ez8tr|UVK4}aU|@3 zs|c|>l}5zO>O%>`@#-=hGbz=%L7YJ}99N;$%QR#ezySb1f8}_-B=;Ff!pS;dlCf2& zVKOnb76i=ABn$H*&h5XK{vp<1h4ilO#PvGG+bO7^X*zYeOhnHb+GO}Ls8)1$cA@ps z7Xeob$M69xinfAnoBFZ4%|6$CymSlS#?+o~K$~lVH)awlAzMOlhu@DOE%K|(dtYc- z58(#DMgqsHQB{ViPj6Db6?4b<)u89CL~`k!#;6UznKT`v2Echh82||^-vhi47zca= zxCZ!yz^Tc<24N$Sn0yg9tm9A#0CEKXl$59|E8m+i#iF7ndkGot8 z3%>H*s;_4wea}AKGp{tXKppFutv>Jho&>M1^b>x%a;FORHrpM&E5#rmoN2rPdroD3 kfO;{-Hwu3P@F$Y{mB8NxTq)dc5LXeMe1d?wy6W|R0jS5J^#A|> delta 2947 zcmZ`*X>3$g6z(n4nKE_S3bqAWsFbBnYUz|!M4>2B6xrM&s61b19@DX}GsAf^#ezDh zao0q0l@O!20fqoBc_uC~!MNZrgC-^>SAY1!KN^YA#Ka{=&v)LmonmYV6{P8O_G#w#4Jq8`@yb9c|MlgijV z8*ECgqs)lYvvqW^peg*g>eYXTUyCngt@spL%>QT!gQ*)yde(rQ9CETL@ex2me;%2y zR_b3P@2ge%RBda=6=G>Zp5yMKRj`L-lF5&?JA3;k3y~Ei0GBhYEjj2Uhb%j7XR=3`RMV68`#v)#_HiId+lSCb1(-Dgv_2ZLql=HW6}IkVR`3N<$1L!rI7;;GecaRLi10gO20U ze8{8_|0giiLtD2Tk%JUCRFRF@ELU-jdSyKx`Inl6lH#e0>H;cba zc2|ysBQzr20%5qA#gR@X7YngeZco}N3bMbEKZd+%tOp$GJl8NJ)r zV0|AzY{Z8cc0zV9;6A`5fN^JZKc){b99L$lWhGtP^DL`e&sgj87tOp|g{4OF`sAzy zJEUOSv4+#5g@DHappNzcc&k-ZWMHx+F({eHu;Y1l+A(!P@34)Is4OzSt97GN2lSq{ z-{wld-7t%KxgsSUzVwK)aEx?mNIx~Zb%|_vF6Q-64fCn7TkhrYsB{3U6=&jqGdrwi z2?MCspqhs%-pVu1T#_z!%E_Jt* z&>!>yK%$O622_AdT4V$xdHq6o{iq#tG|N~c2z_vDE*vXM%grT&>KKLgd1SVD_6Re{ z*R>9J*8B4oeXG{I3q8pOu7jeK4xXUt87$!HG!4ak$}Tt-e_9pn0e+i$_3Fg@h5LDJ z((UpNEY1twrhiDZ`9~5DS6?gSPsDr?+R_aYSXilrtowYwA3|E;S9?nyEv<#{D!|nY zCSq|vCi%9O8@UFe&_FKd(k!UV05k&n05bv7jZ#c)m`X)W!{|Z)dXT07P{i~);BCM$ zzz0=aFmxKjj~Gm>{8}U(*ByH?B;hBZk^t=0CzkHMbT1F%)tfhu|2EOba1e2G>2xNW zrYoTRU0wS5)w=;bJ7cvJoSsRl%^Np3v`IcJN<+Hn7D2 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-39.pyc index 7cf5ade66c25c4b2bf14b530a7c34b6ed05e7d73..815ec46d8f03720ed6b4f53d137a30400a3ac7ed 100644 GIT binary patch delta 55 zcmcc2c$bkok(ZZ?0SL0C=S}3cQE1Z7$j?pH&o0U=F3C?zEh^S`$xklLP0cGQ)-R|m J$(R^h1^~ir5^Vqg delta 45 zcmcc1c$twqk(ZZ?0SJDaFP_M4BUYiGo0^iDsPBbhqAMAS1c7G!YSPch&rQ|OE&|Hsr==DZ>$~J9m*%GCl@#k2RF-5+ rc46)l6$Yx*`SZGM@kd diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-39.pyc index ed388b4d35ba2fef6fb0cd69017959dee93fd167..a83af369702f4cb6785892c49edb1d501e48e085 100644 GIT binary patch delta 63 zcmcb}d7G0vk(ZZ?0SL0C=WXQHXIALe&&bbB)z2=M^ HVU`mBvqupw diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-39.pyc index a18633a7a5253bfebaf13c6a0922b83dc8747992..0be09eee96ab867e07e91ea75beab65940226539 100644 GIT binary patch delta 109 zcmew?@K=C4k(ZZ?0SL0C=WXPk$fVGzpOK%Ns-InySzMBzmReM-?~16K^Qw5rIi@CU@s7MmTVoA!+&neQF Itj^&B0F6B&h5!Hn delta 104 zcmew>@L7O6k(ZZ?0SJDaFW$&Kkx8sxKQ}ccGg03ou_(o*D6=e8KcF(BWb+;-S7ydr zlbP7|GOA8Kz!uJ^Iaz|eis_chhR&&bbB)z2=Wmag@&&bbB)z2=25`jy0Lm>IhX4Qo diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-39.pyc index 3e1b230392f734006850cf228254063b1f199b9e..21230fa47963172002fcbe380f66f49412b8da6b 100644 GIT binary patch delta 55 zcmeBWn$Elaj( JWK5h|0RXNZ5?25K delta 45 zcmbQv)XT)3$ji&c00ckI7f<9a5v$VAO-;#6)b~g%N^vR5EKAi7sLUvtIKKh_CiM>H diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-39.pyc index bab1c689caea0866b0a2b7c4424749a574e4d852..bdcc644909b92685966978540ac09d9a641ab9ca 100644 GIT binary patch delta 58 zcmZ3^y^)(ck(ZZ?0SL0C=WXO(!K~1&pOK%Ns-InySzMBzmReM-?~455D>4CzgEfkRSZ0&&a~VpCftb!f;uc3qYHk7804E?fYO)@; tB%{$}5AHn1z|Gsaa~KsoK}x+r1Rscy2N58nZ?Poh=jRj!PIl%k002QtIf?)P delta 249 zcmdlhy;+(&k(ZZ?0SJDaFW$(#o=L1iKQ}ccGg03ou_(o*D6=e8KcF(BWb-X1F&4&K zlRvVxF`8_yV2@#9GXrWWGM#*jQ%c7I$h^gsk(!v2S`?p>SyW^WlCuPf^5x~nmlgws zlk@Y^GSiE!CM$4l7cv1#X^It@f|P;H5uN;w%h19B#1{h*E6nB8`9=65H&dg?9Ue51gA=yyS&%*LZK{JcW;ezw-7_O=(Z*@vC@iOtGe6W0p z`x#msbBL$tZ@;Tlj+D=4PsyUn5?NeP#SY6`D_*OMV2fO#N8m`zqm>v0loEIy!Uy^Y z*|f2vsg0E%u;K^6*+6jB0Tq`xAlFvSZ8{A0qky9Xc22)PlF&`BM?44K^MGc+F~D&G zE}yNMQOpaCNKm^WmUC6LR0~(D43d_=e&u1-;hV@8Vgn3BwP@FY}$AOmRkjZ{Ex7m$GgCoRZ%_{ieXr$({3K?sp+s4hYGQ=Wk`_;B)!~V(f#@ zEFzq&C`VkN)6S6l>esV`yxv+Ouh$P3tCJig4JwIcaFLLUi`T$JBf&|d(qSVcgthvk13bg)ZwfHJwgVKW<+CmXsK zUxLPO3GA$>zfY&8S4S8I`#pf#V)8qW$fkwsTSg%HJzz2$lV|w@37(&F7Oc0d@#YCD z_49>wPIgF+-1gXFl(P5^fj3M11@s}n2LyI*OdmkY&}o{%R26<){-F6`Hk4X?djqRF zNNke+4bs0Wlc;W*{$8Ehb5ss4>CZU}(c6^da_MPlV$aHzEzw&a0~24GY|*&3J7$O| zO&8Umx1|Nwq4YN3tQ={1WOmvU*8hY86HuUpj;ri#-Jag;3T<{|foh`6K7EiBufS+B zcYA0#MtKph5wUBPjNe`+UtLiuD_6MWCrgXyjM>ZHV=u_}mxb83<+?kbOnwXp-vta3 z*siT;e4h}85XgX-1+KG8A58O9co|gl^7g8jYdp3D0`RBC`Yt*{uH4pMu|nqIk5aE^(r|k&VLb;vZAsF1xm5vkENCG zU-A99Lm(djP!=-AvKIyYmY-}?gdc)`EkiE6^Ta}>_`-yu_%|qJhYN-rD}w{zewZO$ zZ6Y1ksa2mlD417PCyG=s8{p{|0Eb-B{@hHQN8Jb% zjoL3Cg>gcD(H?E*d7bMwZ&|r+oo|zx95e`BVj~&wyiLB1U-NC=;%gW8Vx6a;?!kwmWX;CAn zi_kvNycu6k0tI@4KMG)&pW$3Q9WD4XK z0y}3wge}@HFa2)}m;%?bw?(M@UWVc*Kvm)&LA?+76X4GT+=(key=}tasT=evsJ{X} z0ek`YlEBVJZ>XmEtZ!hc$zf;1%oG{)rFpSog><}fzUn!X z%VbAMHrj~G$2)4XGodF>b(FYO8E4T_IOS+Zc|CW=2LtKXNg=4IS9~^dDa0w|rlzxu zF7BnB)yYCQD^OiO5%FY2i?pw=DqN^K;Dz)K(*u^45RviCrZ5l-_Xz!ddWqnDrpCs^ z!%4l)CKiG|OQ)TMKQ)l}gg_PB9E8Df#dA7#jqu9k*ITH?l0Hh?PtD2bcPK(1W(L+yX87uskh9KpS4 z_&@gO>R!W|qG?r%o d7XTLlmjJ525v$0r0;<@XnA|?ER90_%>%WMxs@nhn delta 3325 zcmb7GYj9Q770yoXGa-qPKu91MA`vc$q&iYUfC`w42_X+cpen7WC-)w1j@%dPoSP7I z2x{A*)~dKIIHRqd$tWU7hh7=l+G#EPu-Z;7{sFf1p(7P!WCkB#u`ONSz6pu;PkVoS zXYKXed)>X(UZ0ML^CP0jEG{n0L>9m3?-~J|XUduk1I$g^ zhUAW^i@Y#Z@>f%T_b5GEEO0uDQRpiq$koQdc zo_H>Mc3M+@qdsa8S&^fU0XfQ5jU0f!k>iJjz> z#p9eqN)0-yfKipE;=G)2X8EV;TD~tISEt0$Y-H9!Fov{n&oless@JfUHvl?~RCoU4g2ZCz*(fygUa*8OZmE{C`ghloSy7@*Q85JaXd`oQKtOZ zE$v|`U!*1cp#cUi)SzKRxH=re$c0=A+36?dcZk!nbAI)V^H^)Ak67@+gneM$yDAih?iFok<(6gTl{loDG(qUlC4@L7 zf4uDQJe?DLtf{QW$v~tLSrhKjy@C5)A+2Qt z73>MGT_0Z88*ZUHvG(Ph zpDeqNiMZ)9LHfkEKtX;K?)D9WIwMu!qNTi|`oq(|?Zu8E3u-F5@TcC>3ag0PJ?%L_N zMaLm{4j_IZo9<{V(*Hpe3@Pc3<-Aa0$fllPLDFkypsG?M?h3vPXWRv<*OC9Vq?R{gLf!_8b4>MdLsf@CNr3`#)l=?^wn2{WBeP z%O8e)6YN(2!hl)^<&URgF`kE&KjkbyI&=N&chG+aa1UUi6rGs&_jis6F7K}H=5o}t z9tj9NKo!_YSIHlB*KD*QK+m8-fG$Q97U^O25GY-QCqSJ9oB`+&<02^C6L3sg3DBob Pf?CWYTDfdk`}%(XZ@%RF diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/__init__.cpython-39.pyc index 3280eb67a6eb83d9328d9cac4b37ccb00fe7f818..dcfdf7f7e79219c12212fc35a24a2e732d3d6046 100644 GIT binary patch delta 168 zcmZn>=@a2jRqi#Kv7Fo|XB=ccA)ChB`67NxipWtOGt2UKR1Z0=?{%EEYS zav*ytkUY+AAa_eJGq1QLF()U!xHLIAH8mwQ vqnc5DGBc;Y5>Q2IVSHLEE0wJ}Dr3Cy4rYgcH4#VzUc4T*FJa;Iz z50XX`A55(ArX|M2H%a?=m&J!fE9Xv&7OchA@T-E)5D ze7E@HV%%zOjy0&i^{y}O$G5{1MvH5CMYH0V{9O+$ajyXelzI0?w&;|3b{%ZtIRy?P zJMH8)%Dm!;~`{=ybaKS5yP@CKEj6NwfJ~!6pf7=P%`B0c$yjVemq^DxB5qXM`L61gO&`N zkYBZ&>byh|WwGXK1vj{zaAf4emdk8b_9Qmgl)RgmAAVkW>LI^L@KOO@z?-K~yojP7 zMLqu3gJUAMEwgaX0$QP=<^TE$?WM4=_kLugdTbr=s8UltIT0iX^ccr zX4ARO0qi^nL?6JYzx?~wiDR!T%Zz>uMyvm}wy~{6bX-=#kMg|jS*s-uZ`Fd|#M2TA z1BHoVMG60S(Go?|aXs6q2zsSLg{h$pMXd^c;~Mt@ySfrhbYU&!0K9=px(89v-G0cm zz!Qh+_HAmCEmR++{$#34zno}4Ij+2Q1`8Ne|Hl7Lj5OP5Ya~X%LUp438!d?{7(;

v?!I!JP z0zjGSuU(R*U)opbny-yMt+?vmV{m<6t2q7PnUC1BGSxkwJOH?c_E`zteKW79qv}p2 zFE(wjsOn6y*kL1L<@2WED9oTwlW=*?kD@e%2MW^$X1R$XBY*F{^;8MnLds^l5JmNv zbk3%GbUfmt{IJLsxnkA1;0L!LSAw?2nMdrFrO zU9=|Agq8Kf74DUs9892w3WLL`P~S$y(Y&Z5Ql;`v*|IA_t#8k?N+oBL=MSM;JipTY zDP{`!F*P89=S?*$!HU?!_~5)3tQPuB&m^3CWjnkC9%~Thj{0$1n6;hMh45&tP%LFU zjXK&NSVBDn5*7RPI2r7<1JdkGrF__LMDJigBTUKX23EF+R+M%X6JYIvCK7nccR&{8 zfg%g7xg&wZ?kC1*LE^iZy{^X%4Kkg%!nP&PJj2GSpJ%Qy%|9iRgYB_`t(I|0`TH_4 z_*?j8jGUH#54IQH!y^qIjV{gM8Pv_9m_vcf*l${OoDxv&XaVAk2b`taVG{vM0oy1J MP|+zPOG7{X4`*h$tpET3 delta 2014 zcmaJ?-A`Oa6leCky9Ksg(sYAB5sF+smKJCtBqFx8)qsUyqJZe#3wKyH?CxF9y+Bcu zweiWAG@6O2CKzdqP5P$pTa6DU#wS1C#~7QKXwtu+u`ix;F0c!xLipX8^EKz3`OV>n z`FryTtFbZOfIkm^b-zyBiez+C+49!Rl4Hv29$4<(2IxigKh985+Ief}1q~mSociAL5@&&5Q*jf`1>uwE8Le-7};$BEa>9N>)+AI7)Q0-(u6*lmK~K za^`*t^#}iW;^||rq5T!(7z|aTCtJkG5^lkw7%{vR&sr`>SSA_gpQY971aAb7(c!WMo_nZ0->1gJLiJJV50M!rJHF|l zE6X}!6+HaHD2fdM3#6^DFLr9Mu}HcgJHbNr;;C-}NfN<9C>T+p^nkdk&Zk@2DTF?b zL;?Ax`QKDl($B{{Kj1?3t8_~sO~>KU*Zt21e*6rK>hG;ebk6PzjDQYg&LLCFcLlt? zFGWUw)b@dRPPMhqBx@P1lYUCQ)82jM6mvTPsIdQr>rjkzXQS`t{ zi!zfpqr+QkQWpGo@;*6C5^$#jz%Ay|43z4WI^U5}J7?zlZ{Ze+#w2(w(b(InraM0t z6`#EnT9RwL?uphoS~JR#WtM;+Fj3Zs0-bt<_kOu+`<9Q(sf!G<1b$Mq$`eqbdn8h` zU6+zv48J!{%Tix--HE(PM)PW>+fCG~e(oNv&;;;%94Se!;H9y4sn?oUt*HY6J(44)kY_0Od3 zBtd<9AM`B7K1U%AhzT|QRJOtv9Cej!CkS|Ga}dtvFe8vQJoSz^{=ZMa54=m!>(Xgx zQ2o7^#BJsDUJ%38FMH>NSX2*?_K!h59S7s~IM xA8Z@RrU>ZY1ki}qp=HM@Kr8Ke4AM07Nz5JGp)GX;ZWGj!!&Q(5$!7mA{{nbr#fty{ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_file.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_file.cpython-39.pyc index f4372467adccd20ae58b193fda892a323050c5bb..0f8df0cbeb2abb73fb86f72145bb2e94dab28c5c 100644 GIT binary patch delta 1342 zcmZ{jO>7%g5XbZE`Xh1D1d=oDOFPuwNS($1V{x{h(mirD{bF+54me6{7x;p50X5_<96U&jbo3EJ-nLh)%?U+>wcK)bYb{o=g?7Y=>YMvgs zCngl{LidIci}+X1qL1)!e#c!+BaN3Da_P)38y{Oj>N? zZ<7OFYOE--mpM(B?P%cGE#0YsWJB08t)LIwGu+7@5D#@sTGh&q z3A(hE{dZW}esp&Y@A0lZ?Yf9xPA20Q$wSv!;Wl~V-qS+7g{7&9XSkH03O_;((Jd;5 z-$LoPKyPT!R{!%RO5BjGzyPoDwxGv*PFuq7r)In delta 1326 zcmY+EU2Gdg5XZgeuWRg>&?JSlxQXK=s%gNEL85IGpjDfX#*F}}fYPAjY_H>^KKn9v zc5FZ`r7a*@5zz%IRjQy*(5erhllp*!lqZmQpzyjvNFX8JKtdIQ2Lv-~qy|6yJU27@ zzuCFj{kHmLHD>nq_5|?v=WX}1*nD`$$*j%GmYJP5p?nyu7SBG_sd~N}-Wg@me<$8% z?2w2i9%qaGY~pLStAJ}^0wM3IS#@rd8a8*03N&mf_V&HTj{7(Jj%kr&l(r=P**?<$ zEG0*H+vD{zER+9)pYM;bxvovoaLcSUxr_o|Gs+goLEtsh!(t4tVW1OVVAVLhM7g1A z!}VZ=bcP7ei_-(3H_^<5q2T{Da4M8LP62Ykql76!9zhvoQ~j`?u#a$1Obz$@pAT8V z{Y82%5h{c-p^eBy;6bvL)HqorBz3CTF}KeEsRjOnh&Qmq4BaRGjMCjGf5u4Hb#qYx&D~Q#RE6fmD>hPr6 z$P*;0mwCl();t&9QtxOup4F(|6@@nhq}F2}kd|uM`{GV&gkA6lM^CWyC0f(tdM0@8 zy5&`&N{*n@a8wJZWkRGU*@oCm4JIL3vswugE(O*bD zfkvP&&bG52l-IO`1`GbBhZZ$m7*_QbP0n>(`x zn?_cN@<4?)&=bqQx{qq^+pJ$X(y}Z06kN!p$ojg;zxoAR-BrMm{5|;2I1G;O1Qp=}# zT1rovqJ`wAT9|2F zmh4@evW?ZplmukRk|)GYP~kyGBy~@$p@kR# z3IEou==U#b!&G$EWEUsyWt-G$K`4NrN zp=rXU9S*^y!YYD5@%ec6KQ#-L&*5w|B=$l@f$n)?Qt?ah-x|nxraKi`Hn3^POqqw$ zV)KX4s><%#v1S|>aa`Ngh2Xa?nT z1p8l@5f9wN@<{fDc@;{dS}~BZ?1W|}EKeV>&1hI4BfDbiT&8yC%?3!ZV}s`N?yoG z=PHxuS6onjERU`{xS6BCh57jQ>$i{Q~K3grU=b&k~CK=YN1)TjIa7(15)otELS@?Y?}5>#RS9WP1y^yGj0f^@a5u?>T2)hNd9!YJ>)JCaqDG=0r_iTyuQgd6F70 z=Ith9a7et8b1GnKVCNot?9Rtl;usAiw!4&Q0c$s1E4#L7P3SHjCa+@u0)T5h1u6-s z2JmUj8@f6ouga&^#;RV!R*vQDn`<8rl_EjGfI21*G|y{br5C}h1LSh}_Bf|00 zI3_jCr}`DH_!yj;trRXWGHK$~dk%K~nkV;kEEu?93I17mc^@e}#K$AO`ly*8$>`Fc z`7(iDa8S2L#C6%&d1v)|#Gp?W&(>2! ztJ3UTU#1o(OnL$jTDGam)157?YAHTUx-jt4QN!a_n$~^<0?a7`HN8J8?(?>vUN`gN z^b3UJ&_e=mV@{EOD?TfD{#t2In|T|)l>K=7Rb`??A(x8*+`h;uebYF#yoHZJkeLgh zScpdluGvTF{2l%GD~0*6M)zSG`1+JVV<~}OLbost55=n%lURmsZ6=}>f<4~48(P^u zn`6UllQlqjFh60~kH8Fq5lk<*AS&dEuHRH~#@IQYROe*6yY4>rc*a>V0&x>?JHP-e z2XI3sK-B@bcDb#3Y3Uc()HlInzDK^-9n(J#p=AIROSC-5>`VgY-Ud++bFNg0$P~F5 z!!TXf&o>Vlvl8m;dY68X?CM#n9G1zR4Po}^SvlELH}Np+jsYG4JW1fw&kH;ly)jM{ zz4bFG!=v9l^rOiZ8O_j*VKbQ9v7h11itm zg=U*Wx-ll+gweIcS}5E4BeJ-^ws0Pqfb4C=Sr}e`)yf%xNBT=h(UbkR6MnD1D@0po i_THK;+uN!%9fo=Sf^aFcV~HpT_?~m2AXL(QVD$g^FzZ_Y delta 3917 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 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_set.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_set.cpython-39.pyc index cc1e70736d9cbcd4c9192851ee2453e1a883e6ad..764836e5c5652708d29c17235f8c8938b80bb125 100644 GIT binary patch delta 129 zcmeCvo1w>@$ji&c00i06^EPt-U{Wa2&&bbB)z2=V(IYAl5sLihht(h2uHmi#SFiHgi%`6HA5pF=@ b7Dqu*enDzcNo7&!G zp45uW;*!j~^!TFG!dsJX2+A_xsDfIvV diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-39.pyc index 65091a6e78d81844972803c76b1c712dfcce25f5..9853f0f4166af3d3f82fb100c84c084aba1ba4ab 100644 GIT binary patch delta 810 zcmZWnO>5Lp6g3}{af~xl6hUWNWvXLItBvhwkwRT5-Sh)gCrMG&R`pqoPV7i6XQ0|dd1E8k79GsY|qH|O4S-pR{-*Z9~lNx6LHlzh7N zH=oS+>a2445-&0kY1n0i5`)VI^wH3)x0F7zlXNZLTYzG zir6-V*uKx)ekk>^y}QSKaZ%e>>Ia9Kt|*tqk?t?or7SUetka>86g>L0-+@WVSz4k4 zV?5DZK6Hv4h%1i=JSBsg2ntJzCEgZ}ODNc|RG1O5@qD_8GuP2WP4t-dwqfQ(mFjEa zTya^M66?jsjgw)RMTG)4^RtJ=S65Q<7Iqd87V|TEr$5`*B$?X0;RX&Coo_F^)+J;zpasL_rg1$2Qv5>?$sVg0;0!aT8uMugTcV8@Tfl<05X{ zxW5SE4-l#wr5k^P2E^@KbzfWxDlVKmgH0S~akz8tIp^JZbKh6qRBV>dpE(shKfZ(? z?00%yofCm*@u3$=E@aDRu+KrA4cUOZtpV%xd8kame6H|FFI}9CtiOcgbJt_eT?XzQ z@CMwu|FkQyY8+^DhhxLkvstgK$p=|qtkm+$sFP>#5op-cz@sf@N9s;mUo zjt&LNPN0NgW?7rZx0z2lGTf`_P{)xqs$L^ajWTp)hP<~2^%Ga@FX3#qsa?XI>~`fu z3=8DYU@@&7XJ3_L@&f&`0W}bj2Ih?23V6F?P`K%=LHudqNeR*c;LMUn-kL~XpacYq?R$ufyu@7t1 zj8CwD`@w*xf)Dgb@br{q+e9b-y5amyfK96YoeQ>zOU<%^zw>ZmJ&qtqYw$&(Wi3&s zf!_+%omDDx1o5=Af-rHf(Cd{5RG}RR$%oQsf<;>cCUqVVOa@5)GjV0yE7mMBLK9yW i+u9@iS=?%D6A^#JL#pV)fp!t*3234IOT%X~OMd`dWU%f4 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-39.pyc index f6f4e097075af6860fe7e423c29157e8404a848d..448f4997330e04cc14bf7641048e300885ed2509 100644 GIT binary patch delta 3588 zcmZu!YiwLs5zblf%U-|oSUY~jik&!KySDQveQsjA%CmLz5aiJ-%zC|h*Sq!Z-sRlu zxCs~sgqkL)o7P7yq2l4TLWwCPX_rD<5@I2Qkce8~M};m35Fk{A7We@_$`8bRbJyNw zi+_AOXJ*cvnK?6auJ6o?f6j|Qw5FzN75z=NeB-r1pGRoweox!xZsPp=^gzAr)(rLalVZp%JD`ssWE`*wTp=F^U20`;?U~{KzeB?gmvo$( z4hh>W4Z|vA17^kuo&iB##CO673s?5U7b|REJSDTyj4mf3&MfQ55U4SN=RqXZOY6di zKW-r*4Tzn9L5&f-03t~cs^z8P4~>AY~%=lT`FEr4!mgqUsMc~1;CZr z-joTKLN#1jc3?V1PLk)wN!_mG1?o!kIX;;3^Vo@N*Xko#LuL?eoTA!EVaZuo#Fd~j zZ4uG@M03QpCxL6yJXl4_La|%a;ieXKqB$&{%s=0}Uxoy9DZdI%3!oW*jM*M4 z9z)6nqC*}hNeKwQ2HNGKB>UKrWO3Dpv0sQI+syFV8N17IV3oI@k%ID3gq3-SC89w3J?z!N~ zb(MG*Qrkm++!-dj)FQ=#C$6ZU0vw;!4Zzr>)2&euVKU5qcllOi$=&{E4e3Y$rSY)clvb_FBi<4F!L6mB-Fg> z-QnWtBwvE)WdP^n0H}x6ANn>7zYcN+fN>{zO7Jz_#1bw@Nnm@O*%0zOX}tjfR5Uf% z-?T-mN*I!^g-0?f%h_4t40uawwtqz2RJZ%@cn^VbOx+lm4Rhe05+Bz=w&D)O=qQ8B zwoA;a>8*d$enJv*jEm6=ttSC|6FeP}DJRAtGz+c30sa`GF9N;Q zBI{J!_TL}mWN{gDLcax_VnR8;DEwmDmaCBSSZ4gPdU(gxb~d?yP32t%-a@|d?ibwc z#hvA^HI!2M+xKk|o&T$}DC{cShM9}TsA5K~9_P{R+t8hix0jR20C!#trxxYx^dv|DWt_lP&tXn4JM1X^3w=fXqV zxKntr{t(Qg1h$*TLDp#+zoeN;lS{Wf^r+Go%q!}H@bTFmQVTWM6|uC*nbj)e)LY!r zatq0{`nY~lPaC<2J~0u&KlO5H+5&S$d_M zSFXmQGtxLKlAD~+I6q{HI}v-!IFvEll}KvUa4C{AQdvuv^fecw&@9;n&(}npl^L;& z!b>Y}b5^)(-T_%F3Rm?rTFFrU&@R82{Wj=V0p9_97f=J318~(}0mVauM+0Yk3A|eX zuE__99XHO-7}C5^azA2KeCBJg~?MuM>iutYUM7!LxPeaeukE|Z#pXR zktTnG6@9ch%wuQ_4 zV^bLxmh$WO+$Hw?i|9{ delta 3658 zcmZu!X>43q74EfXvmM7vJZ^2rF|ivbW5=AkKH5?U^|7 zk5A{F{ho8~x#NGG61Pu@3bV4Z`~mv=@2q>dqAMu0+7@hXiV^2dt~+g8j@iB6l-6$P zjM?2!P9{C|x!~7Cr;3DT+qy_gZXnPB*S0e{;COcWf{^RMhYQ)E?u3Rm@%P6UnOj&w zpu@&!#yLJ}gX4w>9uN_+GAy^|zZCvQfO7Gc_142$2acGo?faZ}e0|wrF_>Rn`K}G7XL<@Ck+RW(+!#HYt7%jtymHCZ} zBxoEANXw+1Hl2)Gl`^~IA&YAY}`p%37T71mzk-QG2*0bSF5+8&DC5^&JhRF zD^yMG3Uw#CUc8WBTYs)Z>{K%k4et0f$!JOnZQ+j0*EckhO_>Cu^U%SJ=xQUAm1)$# z@{cCJ3^qE4S=PeP5u*K52S?CN9mJQhBxl{Eh8vpHk;b@C>O^~8KHs=Sh;H>^Q)@-h z+~uPyEwOt);x_}hpM?YA7*wopLd5w+TyxAeD1)Wp>Q1ey%m1$VHL?2JP(BaC@}eqp zLAX9=m1^niF1QRNZPU^bD!c(oz5@H#0mXTK)bffLcop350$v8JA<#jYMmmi|(`_rb ztw6mD$3?O_lCj5m85H|edi6DNR=w6*w;Jvi&iN8ta}vez=UT4_@v=JkaNFQXD14tl zhek6gCv!}G51b|d(vT>p4$>H9rMyIREa>NT48n^5u4RcmaaTH}YrfEmYZoh_rI^j8 z{6n6Deo-ds^)>R~G?){BR{>m-AAmwQd6hs%ax$B!lf*Ypz-k(;VZEq2$ z^C#NZ3$aZd?`u}?tnKo$pRafIo0Uym-fswk}v6_0%|)k}WqmK4U2*DvmnYydcj8?q-H*K_5s zz(I!oW&8zX5jU5jwKCz!68bD23;7+$1D@%mio-6L9}@Ijsq-C|YWe&jKOTpeQO|TX zwDW~WjD=~r4$~WeqT}YzcWy3etJ__xrhWp;+OVa2%w^CEGmG36=00n(si;K9pql<@{z2hcJZ#qsQKQC5+q)UoK+_` z92D=Vxed2NPeE%)UF)8T^T~s;k5VQ-w{@*(yIbjk z(B&detJkH8l*@J0WjtoM-f|sGsx5oWPGxh3ee|e-^{3T|-o|!ag>NS_k~RFB zscT_4>NzQwRUy)9rnhdZuJp(}1vf_S*il_=o9-l;x*lG1aAGp#OJ*$@pq)`PM}Ajf^fp19gl;_%5p`>4y?7f>v8w1B zD!WO%0UE{YD%H1hIp4W}4&Wu1J?hQA=0;wRyj==I)B(5C>Ysg^#SOA+P`&-u9tX@C z0$t8)&%zIS9hP=3MPnwzNDs$ZnER#63g#QtU;8(RGx_MQ4@D2+k+K1o0c!AFzs{kZ zAUHysRi=q}u1j6s8&$h@@15fLzvkrM@I}AwObgCk8G*75 zWeh7V_Dmv6qsxhN_4k2YJ}zmcv&F*7_#gN|X6dkow1fM9sJlg`n9HYs&z-(1P?N_BjHo!Y*C`YE1n lJ`!ibp>dVvRsin0|HANt!wdN|c$iU+S#(H0Mb&;_;QyZlg9`uv diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-39.pyc index 9a165dcf223ebbe69738e8b2d3882c1f8a9df147..c077c9dd2b197e298c819b142fefdc7d894a348b 100644 GIT binary patch delta 55 zcmX@hc%6|uk(ZZ?0SL0C=S}3cQK-?+$j?pH&o0U=F3C?zEh^S`$xklLP0cGQ)-R|m J$(R^h006%X5>)^I delta 45 zcmcc4c$Senk(ZZ?0SJDaFP_M4BUYrJo0^iDsPB!JD3!J diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-39.pyc index e920ca979632c617559fcb4a8c3d40de690d9bed..e63dba486038b7e3522d368d8e83d6e3e60c0689 100644 GIT binary patch delta 55 zcmcb?_=u4^k(ZZ?0SL0C=S}3cQE1oC$j?pH&o0U=F3C?zEh^S`$xklLP0cGQ)-R|m J$(R^h4FJVF5`h2! delta 45 zcmaFFc!QBUk(ZZ?0SJDaFP_M4BUY=Qo0^iDsPBna9i-`F%AKhO7ZP=6 z+>o;}MmKIGCMMd23thM~(Y1-0jd80iG$yXS|A4i1lKFD)e;#w@obze;%dnhwyIY#X zlka@;Qoe5q-;1xQMJ1l+IZanr6|Ti+)J&zQlyog#-q6?Rx#c}uAx)ZOUDc{&W8D!E z&AWjfftb~>YD!_1*U9wN9;6@E91GKm?L(vwzG0x|6O;G>2nT^4;on9}_M85i-AujB zcvP6)uzq^n+&9{2>PY6W}5`E=no7zN??KI$vMoz(G zF=S1x@QiY;kSpc6+tl{l@gt#eps~)|eiKyfm_JhZ)opN<CF2(!>}{^y0}FqbK7$BQ~uznO|m~_hV+BnSSWm?$J!2&r>CS zKi}HVwR?{6T5Q=$rOnu=$x|adebb6ft}W&1h2u3V(j8@p9(qFbPWjr@B#QVUpjp6h z7M-@0S>$Ch?SyOShcm;Xl&XFcZ9{GpDCHOmHz2eF%`*S0>sGK7m#v>M-XcT4Tu<3i zda|drw=#iuit=LhYBrtA$_0#S-hz%jKv}NrQm1}XQ6Sp(QH}eGhV2&>Gn3&>blY98 z%hEoSMt}i&>|XCaj3n(^#Tqez!3ee|`l<7BF}bkM(_ousW`4U1FKKdT|NJoA-*Sv&WS zHWe70I0bDO7!fF{D?GPi@%$QBp^ZUP>^$e=_>^0YLkkR>*;G1Z=B-37cYSq*PavMe z8H_VxIw*#Xv#QL&bhj9)uJ{#>n7BjODa>rpPp||n==)r|g4lnkU&I!~uw4RG%*DKn z_X|S~(3bv^wNiuDRoL9?X0BZyaOSbXcCej!FNlJYKhVdiu{NPW{_6$QA-XTri)AX_ z-S^u0|Fmpqwn9VoG<^;&220h39SxGS5$Rm7G@eglHzm*c z6h7g3Q7<_?V{sb~b_g+f6*HJ!0-S&sm%Oo#>Zm_$ doQFOS$dwy0lm9%~L@tJV;kvlt2yNDP{02z?<-z~} diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-39.pyc index 554d9d62fe8f9388a227be99a964867ca271b996..3534daab8f5c251a1dec68c89e1cb2650c864885 100644 GIT binary patch delta 4534 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 delta 4606 zcmbtXOH5qX8TN&F00TCD3=oWC2J;%;*yfGR7$#sF>>9@*)YutcW-f5eFhkEBh=I6} zw2sw9BsYIj78Rk2yKyV0a#36Np;l2;rCqg^sw{4$DyvAXsy1q+s`92i-+y6dn9SIV z&f=T%_|O0T|8wr2?kRt`r?}LDg1kNQ_n+Sxk6a_RcC%jrI#lRg)wW&43m_E8w^U(-zW$ zF;RzkJ#9KXjWu%UwF&%*TBZo=5zVyeLi-9!v!DuFrSwW(5oJ5ul~eR#?IF7846k}| z-YGH)ESlHEoE{5Eg=6YuSPQ&5qiJD7oWQvPaZ>(?gMbb|CN|vNLMjg|rCvw5m9)JR7zM;l+V@lUTfypJWy+-)Jj-74~_@QDC7J31Q z^S0+{JnxEfmRkD`ZGD(`&DQ3VTZ0!xnf#NEXRTdEbU_5QfDGL%pEsRTYA_ZROQwy@ z@YCgeo9#I1b(%Iq3r|^IJ1#EQ{|vP{d2A1b-~Nuhh`3{l`k# zkr%OlHI?W``UdGS|7yzUa($b+t<|HlD(-B~8gbLmB^_CgpMXdM$?6Opbyg}c0uXkR@ zFz!LN*>vhgU`h{bW-c%=uf}G+sM2!L>O*oMf7Q@J&!X4JWcvXXvnJLN&;WwLo*R4&oD zr_O^&?IhbfAW6819TcVeo?ce~JFfw5(_cMxO&q^{n8WdALBP8Hf?7Bn2qdw18zfcK zUvXdgI(=3#G&%4PzvCI!F`Hy7jALEWiigLJ7jVMa1Tt8>Lw`F~QJOaQ zupOn^%3k-kFiaR}X}Gmi*{8UC*g~%t!}L*A)Xnp=m^0698AH`ot%=&S$R&;GGG_Jp zfY4M!-a-ih?8PzKsP2&(|LV*U`girdYSuc-ssNUfS}PDbLG?A?IDHMg^Z9nvCl_M! zijz+P?p7RIj!Z@tH|U==vn|^`Qo)oDC5k7V+(~+?_Jk6Yo$GvyCeKKD6={x6VJ*eZ zY3lJ#>{#amLE1i!4V`}Boj3~B#7#gtO-87_?xkJq{FzAo^r&up7wO4Nr0djNKifDi zx0mzFYtKcDm>LdiA+PvyrW14Yaea>>sMS|OhZ}ka*`W^M13fnwPK`xO+W}lu+g%uq zQ!E2ge6>Iu4I#?`ypzrWD^%X-Urnk$@L2$+4+3|)dUdLLzp^7&!od$dj zkOxS#(&sQ`@2+Ds2e1Pidt~sR(n~>8wPkPmq2oBaB}=@ArA-Mt7g2m6)dgepmy`9f zEZl9Q*AWj!SUX1Y+^p!N2^&a;9`>FM;7^l`@}BAI2qH0W1T+jzPyW+DY3=&oS)s zHMv3mI(r zJ=4KgaBnHUwbP}_1iAY!D;H>{zrvkvU#HFfm#s+r44l)^jF5X^)S~%mCK^B88Mx|s zEVsQ%<}Z`ExBXo*Z}~Icf1o-BZm??Sy~c@_V&($9>A&{OTv1-=PtBDzaOaS51f7`j z4Z>-{NzS?Q^vi>@;SHR9R^a8Aj};=0{0H>=7i#u@AP;&wOlLScJ&khv@m9`Yv!Yz3 z&Y=P2J$h}ZWR{=h_^vi{r?uFKB-DfmKp-krJOun4Pz}IKT=W6>8Fvn&qk!iDM*tfD Q2u?~E_GuOUcj(&x0FTe1&j0`b diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-39.pyc index 04de9503594b5946728202bb648fbd1ae6644746..89530a2be8221f855a63dbd2980048f0a4bf2cb3 100644 GIT binary patch delta 1101 zcmYk5Ur19?9LGCz>T-?*Q8Sm#blOx}VMU_Ru$2BmK|NifW%H`TZFin~_h1w~DS?*6 zfe0UbsW}au=Qj)FB*{JwsXA||Rno=)Q)wxsgg#2ln52l->M6ahdpi27m zs_lea(zC2xhBbXW4Lt#bIV7`BQJO+QH+QUy5x1mI2Bz+ zv$=vpLHmcxaaK{hy6iSrI85<^9&vPYBoWWD0dSaOgm$9%Fs-e8!u z7tfM0<}W$G)88xEYaK_9#CQ(T8hTxWro;CA!l*?*)Ik}T^y2$%FXUNuNste%hrm7 zLb24N+~P2ZrP8-trp1twR1Efig~ zLM>YO0;vGl2QPytf=2X{+cd)w(dj!FR{$cJ2>p!TWB^gL6u1ez0d4^wIATfl3ia1& z^fWXdfq!!wW&2&(d!$U>Z^%n!)s5Gq1o(3Zsj@1rOuU$Hh+E{4Od9nzH1IbkCI6PF zm}Co#`mn2uoD!GRiHIbiA6O5Fdu)RA5Wu$M9qfYi94H6IfJtBq$N;8+S3nLRCW7rz iF^2?5;!6Hl#-3Ki$Q`|B$65o4=})Rl2$9%g&D1Y?XD%fG delta 1171 zcmYk5TSyd97{@*9W!F?RY_&|xO;=l$7O^5RNi0P($f747+E#bepTxhLMDhs!nY21VB@pdUB{P_`>Ok)_)L zDZ)_Bb^2ntp~mkExK+7Y_R6X(DYRefw{@E=_*xgC1FSZ^D)$=V&u};ht%4!U$csdJ z^n4DN>`^Gv((CL?`cBf#O6~bOdf^jVC#kd*CQ+*B=Mr9%feXM1;3S75`oHo;y2~($ zM%uWfvoU*8oR~%!#z4D-@~3?n8D!Rs>oo zxpHcbKL^57`9e~8#0U6&K; diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-39.pyc index a2d87ed4cffdad3bf3ca0ba2ccbb8b499584f289..e4365a5c22e4e4dea0574b2580676dcb606885ec 100644 GIT binary patch delta 662 zcmZvZzi-n(6vuIcgJ^7=@T1KSDw$4=RAD3_5e#G?L!+vwf(pS^l`+1HVx_q=?=BLs zWaGztOdTpA2IeXw6C*-mM*agB`3sQX-c@3tc=+n8_df60@9S^f@7+q``-`W{Gj1Io zRSw+nbupus4vp#gmERK{Dm6LKe>Z54$-dv*}Y-ri2mvyt==-Oy#QD! zPG`WL!DVBQWd&VVAD-K5*#3gZPj)W`qKsYW=(oX&)72k?t-8e>dXo04@60E>uU^;ay-m?ti z{e4DZ$1rWTC>aF$cwA_N1jCHeI88XsXrh>e`xb*WBq9{tZHM6@IvZsV9Y$GrIIjs$Kv9 delta 635 zcmZvZF>4e-6vy2hdoj7&?46iRcB2x+B4@-^UEj`$ z7Qx2CG$K4JYYQzbj{5*&VPT_{AoC%_(nfUN9Ha=D;?JLXzxU?7H$Pk7S{3Fv)5rAr z^Su~W-rC+?xGQ+V!kY~E4M?7daO+ttM_=q)la@l)`D`~et?-94JbqQX#soC+)r@bg z;`^Cx-vlSJ98T%jSWc5$#WQYpj-t@gqRKe~k;)GiEFA`i?xxkmf3BxXdbKyRYO1@U+w3MqJ$0T-a0@iP$@xr_^iQ}snX z#rgVKt3BG(zNV^KF4E``uue}%XpQzxge9wuA7`IFe?W~+ce1pQz>-v|dJdv1pokKE z#rl20A<|64Rwa$V8cniDNp3eud34Zi0ow)}&l(a&wM{ZGa%Nj?a+5p~5LrC0WCAu(EWIER6+Sl9;5YMOF1`WYXCcGR`=xBM*Mz-@wP-!bzKo JD15PS=RaI{tZo1R diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-39.pyc index 8bc5872da25cd6658d8cd38bf1ed205b8bb4dc5f..9ee6651d2c32a1f389823d3699003c45dac611e1 100644 GIT binary patch delta 58 zcmX>rd0mn_k(ZZ?0SL0C=WXOJW>#p|&&bbB)z2=Rcx&=G8DAhNBijZ5{vH>| delta 64 zcmZ2uy~vt7k(ZZ?0SJDaFW$%Ym!Zx)WxRRwIK>cBVwT9A^sp$ya-``&NnN$XY1>=ldo6rGXt_JjE? zQ-9hVhGWqjfgj1x6A(48hW(wfn8>I(y(for&Dhr%$Ddi7@p&e<%gA`0ze`v$*KA%H z2-)=~k?aLQ7sU3C4?<;gyltLg=kd8odH9}q3%{B#Pw`wo3KHF^0`#!}_wv%txdjv~1yS)jByM`#0SvO_0hL7$~K24t#pzLqRwg_>%!# z!Y|dEwAzY&!f2C+*RW)^0F23oYYISt L8WBcVKkEGjQka|K delta 578 zcmYLGJxd%x7{2j7yt}>AXwXyd5K+a^=ag7AU zLh?l*2~(sDsY0p{7VG?kK#CMo1X9_gunOtSJ1gkIJoCJt&ok`Xg=Y(zS*?~c`2G7H zebs*FM-N&%)MjSuo(XmvSWH{`zRQzJ;k2(IhxK*c*y!BvbvHX3M!U1};4V8lp3F3f zOa@Eu2$AArc@J@1n?vksV~A9nZ7iXJ)L3NTZf-vGs4QMG@kN^@i{h8|W=58*!1JiZ zsV$2k1TnKI$Rf}%0Di%uz>ATI_mwTOEdEv|$*LHsejsLYQoWremN>iia$rr#6(Tic zLt8u_S{gJl1%U!r6~&LC)559>pNMb6$Az@wBRVIFr7Ss=cX5OQ>|+eNfSQKAzYKc#NdU|S+b53G$aSt<8 delta 93 zcmey*{gs{QeKsoqt)CQM diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/compat.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/compat.cpython-39.pyc index eda62f93accfd58d61639686f9365ee25d13c119..ec584a4d03420aa5877bf43a50c535bf93e2958e 100644 GIT binary patch delta 231 zcmaFQ{gazJk(ZZ?0SL0C=WXPk$H*8pc@?9sDko6nSE+tRer~FMc2Q<=Nq$;tQL(;D zesXDUYFAHc>{?WmU!=(lk!4CtiQ-7h%t;05D*{;#A-E>rW6_b~NGwV( yNGvK&jbbk^PR}e#O}oVgvOhm>vI?s*BmZO%R#Qgq$#txj0tl^O7T4tCtQr6$Ek$_% delta 197 zcmey#{hpgUk(ZZ?0SJDaFW$&KkCE}#0oD!av+R$P);a*M6FB)&8=k4v%E&XhgVj<1p%u*Ho_vv20{|bfI_CfY diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-39.pyc index f262af2808dd2b501ea2da0bf776cb8e4bda2bbc..30343e848f18d4608e00ce5c68b4f5eb2dfdcf4e 100644 GIT binary patch delta 622 zcmYk3&ubGw6vv%3yV)OXdr&JHG)kLFM7oxQZJ^L4rbT<`&C?!?OLin{nw{m%tVTSD zC-MC5o<#8AK??d;=*`Rg140ji|AF(`65YdR9^d!g_syIA)%w%&(;)CJm~YyA|Hc1Y zyZI)Zh#3#3kV_?=a**Mk7*{i1C>fS7)#Ug`?Ga-MuGK&6v`nA2X6Z8l=Ew^HiJy*D zl^%^!7*7&^mX1fyjYlpDZIi?$Try42#G2J(ZQQm#2K7AZN7|nEqfyku6RXeGam^NN z3(@9>8>T$5jggS^P7Q8T_Z@>y9qyV#ds3yK>7nzyaJC%XU>PTr;CT^N# zxib5mFBaj6Gi1BC>AniClG`nV4ucrKy4!4kzui?9qvbuZ?^8C$sTT)Bs<9v@rFZa0o7;VbF2TXOXZ+AlJl| yRapv9JOgiGogiNp>;Qi*cbP_a<*<8$8fY!JNLVE-ULNS(&Zhsn%mKbzdHfffdzPF4 delta 575 zcmYk3PfHs?7{)tEc1<>Ja`0bk#YmyVErg&6${;;O(RmfLd-%<~@AJ&_GP75;f3-4qUFV7UZhog1zixO{LZM;)&<$|J9usRtd0#kW^JP`;)Q)U@F>y_`8ZBzUJhQF5*h|x z0h%N^sp6p0Q>iAfNn)Es3sz{qMc5{^2z5M|+htumpZmq0am-=XZ^$?JNnn z6519sC8EIO`*&>+X*N}wCA!3eKq?tWDJ)XlYrHP@SP%Wu7k8B!FAO{eef&}CK7B() zURPw8OhqUn#p$RKtImo2mh64ZoE>+Md=~Vn<6r)CUgqDwyW3Mgugfx00um60@Sgx5 z$TWCx7J&u=r9qECzYcbAtFq+XXH&gTpcGw7vm}W@iQq9wV_b>Z5dT(M>Toq&&bbB)z2=sxl@umk(ZZ?0SJDaFW$&4%_LT!pPQPJnW*oPSd`*Ylv$RlA5fW5ve}KPmJ0w` C)(-^$ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-39.pyc index 856b7f6ee513e122c707f2a8ac611572183eb5dc..a6ce3005ef2783361c5495c9faf4b37ccbf7ee88 100644 GIT binary patch delta 228 zcmZ1_utk77k(ZZ?0SL0C=WXP^%48hHnO2mTo|~FiQoNF(ND3(Pt5H8AKQ~oByC}1` zBtI>+s94`6Ke-gFM8BZ2Bx5os^L9p=$p@LM1Z08g!I~h1^ki=qJpp;3pr4y2%Pp3i z%)IO(+0C6SzZtm|KuW>t6({$zi76=o`L`J3i$p-;q98&CM1WiXGwe89CZqmjL-rM_ ZG9Xcqxwlx7^7C_w^x>+I)&FDH0RUX8Hy;21 delta 235 zcmdlYuu6bCk(ZZ?0SJDaFW$&~l}Ym!XIfEWdTwf7N%2aCB59z^uX6p|)RfFbeUHSV z6qlmRvQ+(m%8Zi9!pz$lWhb9zt`d*~ssby85HgcPS@Z-HfP#K*nk=_iax(L>i{v&> zX8FzNtO!yHR<8tP-Qq4wE{;!1OwLZtODPft$ti<`8RLsYKpasJp$j5F4uP3|ku8(a fV6rv)3RPK%=x&&bbB)z2=q~(0O{Ql2mk;8 delta 48 zcmcc3agl>Nk(ZZ?0SJDaFW$(_%`8@|pPQPJnW*oPSd`*Ylv$RlA5fW5ve}GTl@S11 CA`X`T diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-39.pyc index d4c424f0252bd7a7d0cc1376305e7e27cd29ba29..4a4ccc3affde5a8f033e1eade2d8cb0d27b1f0da 100644 GIT binary patch delta 83 zcmaDP@J4_;k(ZZ?0SL0C=WXPk!=zBIpOK%Ns-InySzMBzmReM-?~%$25ykOJGCXOcKZt zXvN3!6RB>97q}{r$Us@-ho`FT%&(Ev`1Sk_QD(~V9}6pFoi~(YV)7G37gP&9qVt!9 zww(G@9v4pZ>sb3PVhtPQaM(oZJChb$D5!`oKPt9KH~v$+MQ-aNqi5j)3T4DLCM39n zF%Ei2k{krVbkMZGJ&}Hg`h9*--d=u);SB^fPv)>MOY%cI?75Upx<5i$=s+V1zNPW&@X{r@&KYgbxBq3CU}(12@8@&W7MVS`OfEg_cqr`lJ) zfuV-L(*UaiX2}9N^6efK&k)8*e)GRPk2awA5xzZE6vEFc!fO1W}uUClA|o_r*Ni?Us3)O1+fc zJ^4I|9z-uaNy%CK6TEnO2mb)Yn}?zx&TN82Yarjwk8ftaH_Y4mi+aH=m8MhpJNYP& z3vbeEI=2gaPecQWmK*n-f$)z~a2_c?qGrf_;Wlr&;I~2S@#f}!KUQDT&slAFkU3=a zd8EMtf@VEk7SfTC_lU<%PXs*aF#=1~%~jS=$1`VDXm%~?KF*M}gwV#nG!Rk@mWH3r zZDVc?9k3C!30w|>_^*!l^VeBx_%h#Rg^70RWO|i#lwJ75wE9)B5$i>dEvu)+hMDjz z^}hJsUZ>u72yW1T3<=go&mWDrO9_jht#qlu+C#H^jcqJr#7@IGN>m8$QNV!PWRuV% zrZW&lW1$v>y9lqy*iwg;&5PS)UL~O6dWz;soekaC>vK7p?o!%PKPwAN;L7GyYo^n@ zOu>nVQgxoH9Vwph*XT+UA!QU<0KmpcU(E zBv+EIwp2!XW diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-39.pyc index fce17178c3d23a7164fab4917150fffcd3b47e70..78f0e965509eeaece22cf4ee1ba6a53b4c942783 100644 GIT binary patch delta 58 zcmdnSet?}jk(ZZ?0SL0C=WXPUWKyWm&&bbB)z2=0O}eNd;kCd delta 48 zcmX@WzKxwbk(ZZ?0SJDaFW$%<$t0GipPQPJnW*oPSd`*Ylv$RlA5fW5vblxHh7kZ+ CzYhxl diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-39.pyc index ddd92bb82cd559bb71f251bad15c9c09e6df6171..5c7079cbf03f87c10ce880eef1b612d3ade0cac9 100644 GIT binary patch delta 58 zcmbQpJDZm~k(ZZ?0SL0C=WXQ9WK<~8&&bbB)z2=Ro#^>mSE4B9c)G405z>($H6lE`1HtV&D z7ch&qSzt@T8JT5|Lbh`jGtoa{NIFx+rkp^;E+anLg}lI;Z38Uab|o*O>i?-O{k9&+ z7&{1extG!&AqDo)9w(zr3hU81oLB=9& zS3rv6g{;zvQFdq=m31aXy4~H5cf!}0m)A*>H3gO3%7cA7=+A(8@b6;6951J delta 530 zcmZXQ%`XE%7{*PzU9!~=yKPa#g|rn>fq|_ z8u2BA=2Em+HRG9D!LBRPlY{X3t2|BQQPEDvScg}u54E`*eG?+*Qodqa6cTr33n%46 zE)@)`z}bpYB~$D{Sqn~KU-%b2h>|SgzE@`u!bZ$NLx|^bI(u*TvF`RObpeX=M@jva zZ^%f~#-+y~gtJfY02yYTzC?H$U8_I<2m%_=>}RLGi^Vw7C14zI32@hb%{DFCw39^D z3E+CV2&4tLT-iS`vo>8uB~#D%8${ShtE*&|Jt}?dP95yug_Z#3fPar}sFAaEC>y{g zum$u260i-x1NZ29wq#gV)-08D{m)r@Xlef9j)>01v}A!cBDJbAMJ=Y$NwIL*t{oT4 ddFl|!&zqzccCG1TmwjnnWQS$^oopl!`38pJbxZ&N diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-39.pyc index bda000286beb6060103adab2e2c5c9a120cf95fe..85ab9c50ef5b03b978ee7846f041f99986f65a11 100644 GIT binary patch delta 145 zcmcc1{+yjVk(ZZ?0SL0C=WXQ9V3Ldy^AB+K3l8>)4|5F)_Vo9Q_Y3uPat(@_+{2{B z7&Uo2ld>vE!>?BTjQreG{p_O5;*$Kd)S_a2m;B_?+|<01V*P^3l8nh;nHFjB099%- e-(ruCPsvY?k1t{c@{2%%MIbYf2=2)TnPmX*rYFV# delta 135 zcmaFPewUp)k(ZZ?0SJDaFW$(V!6bQ0%s;@@FF4pIKFl>J*wf!H-Y?YG$u;QKA355a!vA?ZmNT$HsQjI8I{zjFgyG5$%CXOB^-Sbs>(^b}4dS?X~?B`#m%J zY{f32q5Pz+#A$m%2ni&l_Q0X?iDOSafK-VSm`gb!xD`%CLSklLQ(A;K04m%QdYw&+ULAY^%;ecoT_zVdyha9+VOxF~e*D74XM2hpxkX=$yuz+oT^k7Rv~SjD0Ud`(^Gwhize(YY)!@^Q0gfMt%{4SvYUn6yNe*Lqttp?xcFH9*G0(aMoVhpiYjB+Q-i!G{;oNzs5s{C; zPq0CdBe+CRB`6S3$(&Q0B%PISB$Ame6hFcxVhDb>#~s$f|9ZV1*PJgD2*u-*uq9uf zNy$k3AgFHdgDHx>EWeGvskP-F@w47GDHL7AK=CJB!iC`1z>qw_wYvNvaWtmFHK?QI zu+Vj>%|vA;dBNd!!73V|E^j2+>=_bO9^^J{ zAI#ozh2BMjY8?(RI3^?WbMk8HZLKVSO!bnK<{;Fv8V$p2tgIU?n**l3FWLO9&^{W~ zQ*2>_?#sXCbIYnji4i^_xK8jXLe{G)HX5t8bRl4y^krF0Co=;QKPI?}Fc|CF_2m=r z8Ol#%;6UC?r#Ehr#seRa=N`d_1lLIGa=86X-K@26CI^9z(OIeVxLLEnc`4t>hlvZr zGMRjwo?X6yaclznvyDxU2KXEmBM(@X&3u$D>asylZ?-E>EToR~$zc*lp}>2*Rn*&j zvEf;Fa+van%RTiqJ3bOnbB9>}74 zt!CJGLA^!$O5MOO#{^xdqQcpUhqf~R!B^Sf2vp}RR_xk!c( zCU5gyyRDl#RtwI^z0ABNs}dHc6A93L~{92vK;clqQax#%W3tlBTqEuf9!u^7#(U zp4~WrA}A0Nes?8!MF^qtRJD1kfWH8t08$a`6FeX!q&^^cKmsIY)@{T~E#2qcnQv$2 zo1Oi!uvds#@p#8W`1@;*-;8bPDK}SRwqxZA7TA;EG+6FTvl8sy(jRZvA8P|L zybv^9Cfn!p3;D&;c(It(;0(t2OoKV`N!Q8r3~sU^n8QDKmLNs2DE{pl)s}XLySbJ) zOB5X*BL}TvMSN=h{_y$zJ)M&}Z*tkj1KY0$7_h|_pC9;nOd8{-7pAi@FzLi|1c&y| zswgTzq+)R^2mmgLuM>wfDSk`rCC(u+8-`=VpCqV=uX-Lq=bt^d%?oIdQMO(#Io_%d zCGll4uX#f6t!^%n%b4wu^)Rx6q|A07{+KMX`5$GneEpDVHw1)U2HJfXY z;elZRz2D)-LkLj~Kn!;$#ntpPT263=_Fi1>ks&G10kxJI$Xixe?6j7gj(%y(#drKrCjwu$#04inW@?T z#U#!HRc)a6C;VEeLWTik$r`e~!QisbouCOTyWeJZLfS=fexRwH72gju`bgzQm+P;s zIo{f_DaQ>Mpz3X55AJkrqf=efBF^cy_-8P;sRs2T+21C3li(eMY@2GB43}Mtb66oe zab;vx#pJRbN2!K`$N;XA_bq}~5jMj0VD;!z@Gh?Jg@N~QEu(mpc~*_#FnVR*#tM(f zu+3bn3D<~hz-#yiuM=z$yg}9wUd}f|2TgT>5g9@K-0?jr{vOKAypIgov0n;@56EDE z?*}qMZ9sB14(d8-_8>-ZoZx9ozOZIfD`=l|7biI{_AHxwJ2laM?jcmDF*WXfV&l zS7$4C%N8Rh4}e*{H7>g=mS?*dPh9{*VdCiU9qqc%M@IUkNz&+s@3A=8ROSV7V&o;% z@Wsf7nUBbDfa;5%v^dMJm)Y}F5}XpX(SEHcwnhgFGelZaqy@@cE3~qzx7zAu&%7U4 X0p`MCV)xzj=G1FYQwi7cdAR=pfb?`6 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/misc.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/misc.cpython-39.pyc index 56c179d12d83cabae8fc47f2d299f559096aacdd..df8621473351e068d25854330c57d240e7738992 100644 GIT binary patch delta 4148 zcmZu!YitzP72Z3$YkU2|#x@4O-}VB2fB|C+#s-Xe*#rtHEKRoS-LXCKdS-HG7Gt1s z)ka7pDNVUjE44|BN>bHrph`9kBqdFWLK51LAB|ASpwc#~RMLh*qmZYBdcIj>W(}77 z&E0dp^SJk(d+yA;$JwRhEF+YamF}Xyk>Z~|pON8P8pzNUJ*bZi1tSWdbn)e+`_gD0 z)<)v~}fHYjtWd7T!HjmoNNH0$H$u;})Ei>-*i=Btx(I>^AbNuK*|JEHnefRCy?U(psB3ev#a^rbf`78q=ZyPVpZeT0Lp6oHUUA&jwTCfee?b8IC z+8!^S^%K_B4S(M7@TeB?d-(m}AO!z9K_GWHWCTN|$%9-DMKm=!?u-lCPVs3@Ioo-( zs8qD(UM}n;*(6JNa3)kcyPj-GidukV9OhQC}x;e3O7uy==}R6n`8m6 zq3oB9gyVL&g3r$}fKOTsFCG$qf*v%P&_Hx*1Ah!oyZEZKoIOQb5pOQbl5#>2IyO*j zsW@HoGYF3n;CRH;kt9MzWfeOv)>d9Gd4L#G=aN4I6Q`g4statdD5);aLCHH+@!skj z)~`Y;1G)e^2rSR2wpX^&xr`^Z6NBT7(&79yD9_oHVLFbM#|$Y+Ya4&IW`xy02wDT6 z7u*z`%Y({3e%Bn^>Pp!QVrSizx);F9icp&hMzwHg>Y&8o!a14U^=0fOl<(hbd}2?- zJaMvqQ_YKD-3eKWpTC`HS<+C+PTjHGH`A)*o>reV)Ung?GXG`feT4`Cach2eOTbGl z)-Y)~UWSpa@CMhBh|f$I`ZGdXFpr%~$$JVqX0w;kc}=5% z%a_hPjLz(f;$UO2;588b0B|nKjmA>;hNx)G7gbG)=S@rU zjA${_;jCS}yr_X)q{%K6*^93hT)bB-keuDNVYqW zg-T^p#I%-6|gck8&&Wx1an)SVU606 zN7uM1b}T(oV&@?7tML9Iz>&YWwX~L96E(}8UHNZPeJBxp$-4M|!25_`zk5Ywg`Z8vv&pZ`=H|Pe=%YXlt90K5>cDZFQRwkCqTdmOI9ybl5{Qp@`EMx=dRf zRArOS_a)3Mg~TpT8p~w-D;kBF=-)C|bT7ZQ>tp)qm-_oTuA6?2y!~FZUp=ar+-_Jm zNya}Vuu@~{!!gao^4dvwLNRmLlJqgl6QhN7<{=KXcQ6)zy?r-hBci0Eq0dE$Q0daO zH>UB3?ZEHl44Zr>g4g!X+mJ?LrW|(M4REf}4>}h6yd)&n7q0j_9oJdW9WQCLIEe`) z7Fb+d)!6X`rjbG>0gq1lKxSfng7(!HNGDNHSLCp41Uv@)NQ$p$i?_9qEks=9-`4-F7~WGu{;wlvZ3(Uia-wLF{YTqbeMzKotjB&}`_tHLPqsVTV@oOe zUrA=aZ{1i|S}noFJOZiR*{uJO!~Ig@DDQ#ih*;m-p7kRd`ZMg)!+XUOy_LcBP;LNh1QY>U38-8uC|baW z4;eKyN>yKEP|ZXmL3)e@={N`R(W0rrQDZ2Op~_=HYRaP_HL2T(%njS5Dr|mhp3Vt1;;x;O)dHDY}2MX)*>F>^i0kote|tjYBw)ntzz5eS8|rjR26S2 z&R#}BG^b1sjhh(mF>Z~1b#@5qj z50J#qcF^d*_K4R(b-+pwYpO{fK~ZIZuOSWJ5AfTu6wOMFYC}Vf^d`U;LHW;|8DxFb+82a^<`D zVH#TA!KfB8c^$-0iCOoRO+1F7z3UAa)dKtgyqWTs0H*+_0cQYsQR8m_@b+S5Ppu=B zV~DPQei51lfcF8oy7@H#Zc+QjOWZSd*Ub!IBIucRN9DN~HG(*O{&*Q=<$x+cEuaO^ T3P9D^yX~lqsoGB2_V)h)f|&Jb delta 4077 zcmZu!YitzP74{wP+Pi*XgKe<0#`v}NV(hhfnYDS?V8<_PAh95%sV2+rcs=oYXSp+r zZD2)aWyW-CnIuLlY)#Z5t{_&ndwx`n^sVvXtU z8{IS3H?nu^pikoKiD)v#&P`Soma=?Ibjx^aQ4`xHl%i=iCf+UDP%v zc7}EDgg<9!VoD499Q;0TFaIl+*zl-FJAbs40j^hCvby%pkw*DX$!?k3}ROGg^xFg^@pci&7%iNl@(wS3wG z-B;#iGh(LfI$^YYUG?ImF0SZtEv9FrUA$0!ta1jvX93dyySv>hJ#3CLQz}jjuMnqJ zZX5vF%#A2UJgDop89-SO)F)+Vr!^kFND|#akR`boKS94f$;>_yjEcjh)yd{ngUl6y zFo!=RzErWL?if9odHaLWgwn^k#(j)GOrngS-m0i)C&gzK?-YM?i7I)m@~f;B3-D!| zP9qVIDrWXnFwRvH%}b`#+Gb{RZ92o<_dMEg+Jv|>T)-&`fnLRF`Z2RZTGVa<{i6i` z!Qe44+~aCAN{dP;ToYqe_sEtHOlmr#4<&TN%;CDh)j0nS$>y2q)YYSko^sj=H}H1@ z1NfswJMkm&Z_y7eBzP#Aer=C~({4LI8=WQwu^yO;qfJa&7bf#)v)tvvxk?Oc@l6x zY;}V&^a~hS3a8vlB7TQ8@K=eXAo2nlWVs4hfmFa;%)u;8h>0Jxu1fy2`G>3;)}~8| zMC7QNSp=lu=R~}vjGYr-Z;{JhgWxv+`vPyaR7sbz#DyM@*wp%<;|ITGWSlm50ZvJR_;a&^VPIlw{Y z@Jwa@4*i(<8doE-ZiKajVRPRpUTtq;SCb#Mm$I^}Fj_jbDBCbu_Ln}B2zDm zQ|e4dUo0`j1LEq&RROdr)2SNDluo;8Hm*<&eSnz$YAFSk`*gKY_&qJ7g{?7A4) z^tcCMP&WPrvws6@aS7Mv2KI?)-Tc(nk4g16?3J6Wn_KM~5BItaWA4qCgNm9ml0CCSK|A)?+?O4UEj}1dq~Y57Ju08O8-$YNTA2^lx#q z!2e(%jgE4h9HSgT`JCvm@u*6#mmWDo@+1N?HxWCW&si}xl=@Nh5*3#vKi{%8SBaT!Q#1wAi{A>7roGVT+AoH}hpW#^uxuO=76eBic$F;@b9Ap0q7u=T!ikrSR;i z&aWmRy+?#AI(*ea+41Za4~VOwa99en7~$f~plu}w6UIa;iahY_4u`s1q}o*Axb&Rv zzIWvs;!xC9I_%WXyXPvcc@O}vTk7f2o(5Jg&iB01lI}QOFd7Ny75o8(u^`BZ;Kw`X z%5Ylq-vjIu?$~vYl?@68Zf++$yKAoIpSL_yN~~GdEe&jUZ=3QaSZ@K|23Yeof#?G? z19C}WIu2=c-)PBnVZ~&%x&~6*O?yyx5!uC-JBqT492`=b{Tf{zH`f)xb}b|JC=lvBZ2W~(S4*e7jf;velE@wI`i^;Yk9Qgc^h zW{#@U31I&KNaa<0Fwn>XqHypUds=)vxVn2DL0OG8ClL<^seR<6J_@=JA)7FBqDm}6 z75xYiP3IxnqnY=su^}((6~~5tRNRNW+R`Ze!_BN;d|~)pU|@*~zNq=Ad|K6&GYc8c zr3?=dmF~0-x(9{%Kyq}q#Hw&};qYNfMmznl&zNRv#B+QPtk~UD1_~0)#%OfY8u3o3 zj+uEOEoRV{OH@6?caer42W+#Ps+yS_)glo(aCke!KLP9q+z+raTR_D?#;sP*PB%$X znr=FfglqI0^!*}68)(5VjtUx&>FzN=Z1FQwKLQ#X!0YELF4qyOg0QG=5z=^D^(kyvO_-_14X^0U93wcT4^<;5^_005>px4sZ#8ONCjK&L-7lFrsjN6`E$i`+)0!PXIUv zc`m>@TdYRwxgXDHpxo+iwHUR4y|6X8AF?*UW{ B;GF;f diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/models.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/models.cpython-39.pyc index 1b354cd8b8b298173e1967f9fafe982ad7707b67..d25f690dc0ffc022e06d8829630a7d5b721e3e55 100644 GIT binary patch delta 58 zcmbOtFi(Ixk(ZZ?0SL0C=WXP6W>P5C&&bbB)z2=CNw19x+WHg57wb~Q%*NgTZbhHyK;wnWc(O5>9glQU9_j6i}2uRyI) H;j#h%u(Mf* diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/parallel.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/parallel.cpython-39.pyc index dd7823fb1867ee219578cf17af6c3d755ec983a2..d98737e0c29e8c871c6a8d6cddcdc9d363f8fe96 100644 GIT binary patch delta 58 zcmeB|oGHnj$ji&c00i06^EPtFvMQA8XXNLm>Sq^a7MJ9wr4|+IyW}UA=BDPA6zdmM MmSk+MV-;iv0O3^z?gHV`2R zBG^HM6o`-p5i*k<*(D~M@d!@-%wfW)Fj<4Mn-{E+1)@=L@&QhNA!VRaO&(;UCM$AD zi-U~0#g&non37r)pORSwHF9$>mmj0BEKstFO;;D>ks>*eUGkH+a2r^GO-C^cB&Px* uR6zvTZE7GE#DO3d*wN}xr$#brPM*MHBPs@xkpK}2AOhsZBF)JUdHMi79Yt{f delta 328 zcmew<^^1(H((5$YfU>^2P$ n3*tZ!3+!l3s8b^uwI|Qwu@Myq$w-0-B@h8}W0Cgc*F1dy_5MWW diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-39.pyc index 884c9b2b341e565671aa5864f8a6fe4d4b861fb9..0057bb20592e2879472f87f624a465712cfbe0ad 100644 GIT binary patch delta 931 zcmZ9LO-~a+7{?iRyM0-~mZr3zQIrx|Pz!=0f*4-JgQg)-5;GpwrMtFkcXyg+w?!_# zd;{ZnG#pJh8N&zgyaJL6?!tr~%RAY`=s)ObE?2!pxX_Zx)j_LYdsj=~I8RDbzeljck;i5JMc{Xxa#U!0^Gg2UVz7u&za=fhMl4t(MLf0T~Da)BqjvS4A zR`R5<_e1$aM$U^EJ<%!Hu)Kz?Z&S6hWoVrN{}N00)2Ly!EW?Ci1oD{g99QDQmx?II z5fcc^7DNxS!9^TNj#oX@$Nl&Unc;8ZH_7m{Ok(K zSwvXzRaA3`YlwNo0^&Mi5phF+_SvkedCkoRu!`wN;u}y38HNE&&_$ z!Cm^3c`$Jr$1y|{Aqj{)q07aI(CVNXj5rJaGXb48V=waP-DY;%T7SXa zi^=oo*~m#v{|XZmjwbKunRqnBc<{}(HHAHV`DW&uc{B6&{a!d&P>rFXNT2u)_r0&` zGii~ZD7ux3;h4GsC67x2_xj+pQ2cQ-6>3^WX43$31FSmDY&Xk3`y#y|<18cpjExCZ zAZLg&aV`xN@Dp;wb&6obP8xZ=?wP#-4I)0?xatS16{=6K|XGDEc1 zU*$X5yoe=+yPcbsSGA2MSBni(?-~)?a;RQ(YmUzqx8_%CJ|8fxx@A((LNJTfr&%mK zxpW?B8sP#$PqwUof{t$>TS2&qu!^vTu#S*J*bu;@wp-G@TA>PVk$N7F)I4hHHmy^ek9cLbVL3zOq^CFKJwyk$IE9161%Mvaj0N{gy=@{UH!fdlB=Idp{ z)Pps_Rcx{M{^v(IX|}>A?-DhbH5hZ1>51}6n_>b^r}cx1yop?f9&uN(N8knWpnQsj zl26D4Gm?o!;C=N!^b%Q$y-hC9y%to9hlVt*#19#Xjcadh%j@0M z>;}>k7ybaG5lCE+IB-CMLltqVfGa01sF%GU6$wrtaYEvNnD1>rN-FRH#Rn}nYFDq8`;`+z4p5KR=rl+G^^{?daWS} z%BSg!F@W;U3XxW`@H7|?p=%f#Xg=y38y1RDUY+JS!Skj{UmVK8aa0GebsGBS+9;hFk zEFgmzpTprX!0{(Ea>xriUQN(RR(uox_~eW{4`UrGFq9Fm(ct}rS1S_B4|u5Fab262 z5Ox0P&{2HYrX@TpzrH3xW2%ylj~@mK0=Ruo^1pS`sVUn&;Lgt~0F#m$y0fA#_+ z9u>R<(vVq}TiN6>(`?yI-#5+2O$Mtdj_d0rQKz&5!#Th#V3=VZ+a>X<-YdO?C6z*# z93~1UeJ(*#Wl8l1>D(+-kAnS&{agCwqmVOHf;&7b7Bf3lN}F0rVxZJ8*|M#sv+Ety zw~B}~2A8oSmyvA6kC|0=LX1!Rz?Q_riArfWJCyVY748*rCi~TSD*ih5;DiZlPfoTU zwIc=d;pAak6IyQhgG0)m!O07NBmiT>#{g#m(3sQkX&!eyiwF1UM*a#8#sQZAD&PvB z0$7s}>W>v{S+;$k;^Yw-o1X_KzyDqC6D2|I$cjdOV+~6~4HI0>dC%k9U_B2&0tb(Z ztmH&ds5_*1Q9R0DWZC`V)QZAxi(7@_Q=`3CXv!{!g`X# zFzNcsUNh)M<=4fPIX4;*Di8WL^uQW;?H)J#J*Vw+ddL~mY&wn`G=rY&;E7HlH2!ut lJ%$CWXm)6_bZn8tNRCg03$;rFx4mmymziYv6|r1=@n3*uFtGpt delta 1513 zcmZuxO>Y}j6zv<29jD1StvfOP2({CekST2)x%p}-AF1Qwrb!x9N+b}PPVG?{>UgX- zlgilus`>*eU4g`sB@(Da`2k%abp;EAgkBdcU{k3e*j2FMoo6RDp_b9g3{U- ziKOIPnurFWQ@btbq4q*9Elq!K6gS+u=M<|BuP<`%j$2&Y`Y@z_w0kT|pGLl9M`$}? z(yX3lqjXh2I)o^$AVY0^nVIyRet&!n=_5Q3=Q!Zl9<9s06D`M-$E1hR&&FSrei6Cl zhL+YB)t`Jb)~XZ~D+syJZ~A_NA4k>+K#$qU4_i*c%kl~065>qP5|Lz#=ji0XPp41s z5-cW6zfreCccWGJxXs;Lp4?!oFJp#I#VuBp$2aMtxHXNOd=g**p11XsbX<{7ph<`` zK84_&$MKgUY@FEeH>^Mph9}=Xi+I%q=phWZ8M@rA`SPzFTG37?N+9)^)AIEzCI)T0 z)^LKrw!7U2t3Z>+LRX@XjcfUHFwO&x0(zBZ@LHlj4KIHIOLZi*(S9Pe6K7*eM^h?4 zksaMj^grfbiSq}cv(Unu+@zV28)a3t>a|h{M->CLhU+vpTf67Gh>U7J%2=t8zDnum zk=NJ>N*#K{O7zR2Qoc7-s^C5 z`_w%N&n#d7@CslMa0&pOc|n4Rx47SOdAOx^mber~;Ode1!L!84X$uFYIjZf^mbMWR9;c zW4QuY1zZKJNw5Zb7h34t_d~u8Uk#wt(cJd_(VV0AvRACwDirAZY-&l> zqS|{6oZeh?+6mh`626sB0A=JC;fSt{=^9IAl*c;8J+MBYGr3eu9e9P7a(-td)PWEu zjNNa=ZLe7mcoMb|+jg2wKXgLRZ{kvBkqKWQuExKJm6{ecO9oz1O<$RNQi=G54ZptG Oa9?MV5tL|tZ028;04e(b diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-39.pyc index ed3b9a2a04b69008dcc5cf701d3f0d9083975b00..d13541519c636e9223fbc46ac8da8383d0e5d3c0 100644 GIT binary patch delta 621 zcmYk3O=}ZT6o$P{n&!g^Lcfw$G_7VxuytA+Y!z**v|<$zEZK~UVKTW%hh#G4%(S+y z1QA4co|Pc(bR#H|wSPcYT@++ix_04T@V-M4XYtIL_dRpYx#xbbAJy}YuIEmur#toT zOWxMX`{s7wOS4N}7zJ%fp}8KoyT0s4p}BJqZ4aJm&rS-9Q)ye2xt0E9Osl_XM#0jZ zW@xuOl5P~xftAB&lXSg#9Xs^ECxg?J<<5g2$3*m4nghwI#S^$T>B&Fa4(40Bt}$1L(jAa2==s zX<&s9M;rDHgloV};Fdx>v>SQ8Bojh1^{M}+h8k;XN3;(A0dN~gdfZ7|x$n{@w7dL# z?5*you$DTm!I#E=i$$KC_-s5x$|`{Sq-BLT=Y{qYZ>R0`Bw-`e;6D@R43wZPBxGFj zBF}Yt$tnIV41SaA#fIqc%i{UdYY^su2C&Ruiyy=mw@UXf%t9yw$ue+4N^U6Wmvrjz HQEBfl6JwLd delta 613 zcmYk3&ubGw6vrJmO`60Bg~lcUp{6Y%p@FE4t!<%dtY5Zjqky(mM8mwFm=DykeN=fp(sW%8?Mn?8_vQRnA! z#OA+~Q)eeIVBDf2sgCn`VA8_$-Pe0td&aXblW3|S)a`Am^6AWDc@qWRQ9woFvlb?$J3c(pO+|2oHu!gLxP%t8j)eXO=}0$%rrYA5 zVTf<>Tz*yT@U#5rfLrN|YXHphhx{wC&h5hTSPcRk`)dX^BzI+Qo}0A8-wFqR0MY`K A?EnA( diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/urls.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/urls.cpython-39.pyc index abd6047699da3ab0c04c76064d7a6c9b5ffa1150..6e819915b6552104302be7631648dcd5aaa0f9e9 100644 GIT binary patch delta 58 zcmX@YbB>2Qk(ZZ?0SL0C=WXORW>hHF&&bbB)z2=4PAf(>0iZ*Q1Shv}smTff znYY+dD}c@@)?|v}Db6fOjnBB9+PNJO;MXATE1yer`c#PHK@Xh{uwYpPy624P-*h;R6XW X7nc+jNr1$_7N~<*8emVZ;V}XLkYH56 delta 299 zcmaDMc~6o%k(ZZ?0SJDaFW$&4$Rw7ppPQPJnW*oPSd`*Ylv$RlA5fW5ve|}7f|2po z{G0Px3PF+&S^XKMHXE{)F)>O_Ucuohe2X(VEj>Ob zGcUFH77K_fQkcxb>B*?F*^kqTkxdY2ZIRIAJ}xy`VIcDsTWUpSaY?Zz(=DFj%#zgj z-29aIl+2=AlP_|mGwJ|soy4sI(!vKKbbxkCOn%3$DWwbKYKq-r&&f|u&&*3N0vUUY zsVKEbeX=2sfvqfv%buK{TacNPS|ktRu_Wc^=M-@RnGm!1L4wT1B}GM2ATh8dIv|!V J*ph8LMgY%zQRDys diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-39.pyc index 348bcc97324d353e738a06b42bb2f09d40150f04..02c6f1c912e4a27651a32f385b34f6077521f664 100644 GIT binary patch delta 473 zcmX|-y-EW?5XZBZXg)NjK{%r#3K20W3_(;vqDBxK6+cn9<~YqJIZW@^H+ys{YTjG$GnCNP1{Y@86sA$J>fF`kL*$$lynNK`NG+lq z3?kZL_jtc-fvZO?yW$w+!Xzei`KV5^qWn^G@gly{LGYXMGSlonT%~QA9s&QU74jfz1T)MnYj1JFX<_yhM5rI%li75)}W-7~cz?}DcAZL?1znp7wWB>pF delta 446 zcmbPg*loz2$ji&c00ckI7jNWV$}E479BALr9!w43~m&yd#+q93fudU61_=wwg+)of7iFMd--=gkHJ zL5%WXkpPg<)*uu3$}>_^bK;Zp^GZ_lN`P)zD5xN750t3`;$l7^!N9`B#KpwK$iv9T zsKr`jzxkeE8KXuhP~sL(S!z*nW`16LNoqw&krPm;NCHksf>;idYlLMv9Dq!q-<&ot z6yD6l7&bXnERf9uBpo?Z;N zOMLRv(^HFz>xUFFrG`B(*3nF-NZ~xmYhfvm{Cy zQ#d!ZD7myKGchM>vOHt77AMf8A`tPbR6ip>H&s8oD6_aEKP|PWSl=Z-ximL5ucTPN Mpt2-m@+`(e09I)$G5`Po delta 119 zcmbQr(#^u1$ji&c00ckI7f<9qz<6uo89CEiq6L`+dhwZgC8@$;EoR`Q3Z(?)!Z2nxC39s8-7d;Mtyg^M&5Z z=a{*Zf9*{JqYmxCj`n)8&%JFG=|tY=N_*F2ci87~qP@W=>6w|r`&`X@D?FnI!L*Y< z`@prC>5!`zj$p_PLIZ$N#UJ`%qz57xrB1gW`hnWg`&+5H`AS}#Z=t~kaEUsG^<>Pr z9#`8&T6b?SG8hV>jv_OU-a;0k=8(Wd*ZObRaa{k`ES#WGTrOruu9@pavs+G^pT!o< zRCUxZ8r$B0o;&v2Q?o#HHa`>?)jj#h*GVXc34CO4U&dmj7EH-m&9%&i)2J+gJhfm1 zQNm2%EG(bKz%$5_p%OYJB8qvMd(4R9137WD&(5nW%z`1tva_jH!1L=5JZ?T~P@Mw; z+TIUzKpN>t#uF(|N|!4*(UinNpR1brUb;Pxz3q9kajyX}VOuMQQ%I(E7%6lz^Rc`# zdl+>V0!281&_+0EewW+pi&(BATm(qTJt>7+$Fl1CT@h&A*gkX4)^f~ ced%68qKPntM(An_t|C`sp50$#o>rFr0(k7BJpcdz delta 718 zcmZuvv2GJV5XJVM&$){Ob_~G~AWj_686u}hgM?6GP?QGA5ouB#NA5&cZ0^kLIbaD< z0R^I)h7P3zQ6VAm0aR2V%KZcQ0^|l}E()R z%mOYj!H%BwU$X}9k9N=~wu)JURopD%VOYUm#o5C?vyvWG?3*-U*M8faC4=>?_XXqX z-Q=;a(=h3$^pk!4Bvu1h#OcyXlbbM(?kSln8AsY!ItAH-7V}od8+=%rZ(Ze<+RTbR zC~X9%o7@v4AnGM!&3-PuUNaU%`*E_q1zzm`-ybQp#Mw2x>pr7b_``kW-D2WA!xRf?ss~c1 P5sYZEE3M&+$;*EM&OWA} diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/git.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/git.cpython-39.pyc index b19af899ceef4c16f4d38dcec3eaaab75071f093..b51a6786bbe760dd96ba6feef17c20466622fd69 100644 GIT binary patch delta 1828 zcmZuxOH3PA6z#K(ZEOPtnO_KC>|iip)0Y0irvd_mR4HvzM8bqH4ED1<#p4;>8I$6+ zf+$kDX;mq&&7unws(yshMJjKysgz9{MXHodyXdSUrBah+R_xNg`^>MXUL4;!_xtX< z@BXs%aLKP!Rry}vzm=BFpZq({kkOyjHQK)ds%hzI3TFR=o-AlIZ<+nZnw2dzxgI%u zlIQf9S$X2jd5JkZ=SVx7_596o*!#w@Fb@V14mOc(KhRZKH!M}pn^Ng>ugBr;LVa)P zYu_{>ZS1kX)7^(moK**!$pGsPM93gJ8z{Ij2DF#%2X=^m6y;sJ2i1A^0Dh0Lk(%h~ z2^7n=C{1y&T|m>O?aHZnDtWjpn^{HjqL5cKD*2W{$tSZiCnS%hWKdxDnt~39mhRR3 zK_cTA=@>@xWffCS>YAonF((|##qQS5_(fWA;8>})?pG2U;y&91M){xQo0^*zLi9#3^x|urgx3)+APlgVg5kD<6y><6X-BBzATc9&g+$ns;Irr= z|Nc)&OK8=!56vibmj0=~M#v1i));nUaj?K{HzvqDvm3`du>jkp=F>WOQFjtSv=&FA zoK|LIO~J)Z{JxAZjexn~5(m4sV5Ag_%4T6%(^G{UHDi?^uJ}-I&`?Z5N;Qp~vIYyt zc#~R6<_+P4QEI9o!}Az)837B8xeiq#GG{ouUGaaxL1oXIA6_2e22U%|*9jN-pNLa* z$K(8pO%UPtX}bcbNiEc76-dS0hYl~Jujs&jUdWYtS~dt-VYiP*UK!>FQ?u|E+7S-L zI-r_v(S#0aM$IP*kPE>(sKt_EUKqI1+Hpw?)q9+<8{~{?@i{;r+0tc0HDvAsV`%Lu zPuU31?+jz8;`G2P}6Hg7k@E}Q!$4aWxG13XXLb^=4eXhw>CS& z6=F`@+-q+L_hTMSImbQ?7YExg!(KSi0M|hSM2Qj`iX114rHhd_ zNgM+dE8}tAz<5dpehXKTaU>GhW-f{*!WEQ0WIvzi@QDY7wMnHXC+<4P2;1r!C#Tq7 zU9?5$uwlH@$t=~V?aosxrzg2@syk6F`INLpK{j#)6WZCW?kKs*?sxxK#T&dg@L;fw zSo4^8TsUK~irws3!WzOg1gwo8bHAFSP0BDk_JFLjZ+k-Zqv%lHb|}4#u)+T9xj?>R zFZVXjiE~yUD^^GvCA^7)#I`rDgJvjJ7S3@6e@y#{Z6`mUO#n90L+p!Yl(yKd-rvc0 ztk8FrEU}%w`SlK@>k)boTnGt-lN@Y+GN+iPMy;%#0w>a9HAGPo`^?#L4z@JY}T}~JZ zm=wNX-z1)neTLdEQCpdz)>%E1p#VQ1DfXU+Z*_xDG`xyb1KN4!CeM$*`~D<+g47-M HTmRa>V0XAz delta 1809 zcmZuxU1%It6wck<%>K4%O8%O3Yj%@1yN$DJMfzh~+a}pfidy>)O03liLKS;OUj!9up|x1bSga4e6jbmf)Iab(6%?dGeek6|hm>tseGw6y zJUm^PIDB02SnwE2@KeFx5c8p3{li!Swju~t5K%A|3U=K!ZOakfd!e9DNz-`7yA+vX zY>?lNZXL`L^90TC7f;a38Q{0-% zzh7@DJL!9ZPj+lOFiBx6m!iW6B0yzDplVu%2x44tDw+sUU}-f&MCL)Wij@Kqf?w;1 zvy}I3$B&HV_=lan(MJmM+nqU*ZhCyGFqJzr0ZAm% zF%i_DjHMSK#UovV8+IcLdk9Vu?Bq{(B@?S_v6(p5bpzBk zw-Y_Qv-`VkCCo|tVYP-yGy7Ix6GbClxaS;W$M}Wbq(U8o&TsZ+*c|`0cWjB85&_dH z*$|?!eFRcevPG+v3graLhO4JP&Rc#S;qC&-*UO?5*HedF2uzhn#!b=3yIN5??*_m9rj-OZB z|F1d#5A`pn4`RZ-FapX{z#mzssi>-}l^vKPrbS;I=zeT<@3iAJ%fN#7)WFM(HTccV zL!kqhke`M_{O;!Xx}%hR5Fs7HQ;ozEN{*Nld`Eoqo(bZEtuxw>u}~aWw;L|mv1Yr5 zBVr}HVd-cT`V>m*7l!%yc!>>r_v2gq?c@!?HzfMm89tiWt56|G@H???em3#hCK9I^ zQq=_m%+g{rfF?hcPy1k;A4&F&O3f5Z`Ohk?*;HbURc86y$>zyH8o7XwpT6RMc-M#` zn`2Q~PVOqOx+`fE5iK?V49k_KUsJo}%@6HnD%EXm_!cp~OoqgxWvDc~ zO7I&0W;hX%?v~1Ve-7XBv4i}RkujF%e~cIda!iV&IK_&AH(Id_w`v!0u9eEH7ZI)G z8c?WL8xHDqHMNah=66!pmPB~Pp3tNQ&=RI)y3MGnf`Qv`@adCgktRvEKkSIwI!|zs zfciy6Rytg(C)x97*4F04Flh7jumJum%=ZufJAH#);Gb?E?0)1y!yI^?;7$I^_LJ;m zzISxfjMSu^Sh}iU6VPFbp_U;x)?hCC7ZCV2en=nw33 zzV!H6W^$&!xHLow-2^H@fM5p!T?#zds^&N~!>!ml_=%R6K1Gpy%z_lHCy-ZXgd&&V zGyy3LuMnIem?e-8#=8_n5jx>Ag(Mhw1h@F_YMfo?q0IR$(hRQ?dk#Uw8c?m8^O?E^ zjsYL=Yngk8-lx$^G#bWt>N&eyHUPdLl2jAHqFt+-RReYr)g!5y-0`s&PUPSXqHgn_ HvWx!$4+^)7 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-39.pyc index d069c25a72febf17d59a932de83bff224d515987..adf4798fa67e48bcf2e219d3c2c227f5508bfdc8 100644 GIT binary patch delta 422 zcmeyT+M&js$ji&c00i06^EPtZGb@zoXXNLm>Sq^a7MJ9wr4|+IyW}UA=BDPA6zdmM zmSk*BVE)d;7&SS9?H^;*=5Tf{Mn=oYNgVTlLX4bwj5eDKI0YGHZGk4PWGYesQbi6x zLX)}33BcDyaj`KPxB!_|g1WjTsksF?i6yDF)p_|TskLq)MIg;Zu0R4s*W@eQ zceufZh=JriCLa_M-h7V7hEW`(UXuf1S&;@vf#zgIJ`o`;5R(U_0Oo?p?tDKOy(T;G zi?G>&B<&|h@vl~aXaVwXapdI}yfHGt7WM6?AHV=?a z?aAi_Tx_gBOev5~?&O@r;^N%Yl8pS6B4?1W8;EcR5zHV3EJ^wKIYpizz8{DPp6o9u k%NRL1SI~oB2c&>KCqF$sGcUbJWAYKf$BfaFR|tgx0AP)1?f?J) delta 401 zcmeBB`=`pC$ji&c00ckI7jNXYXBNxR&rMCqOw{*CEJ|@H$}CIO52(y2*__4vor&?* z8zZCpq~crbK%yYAB%??hB*Ozz53_i3Am0yZf1rq4$Su~Q#LVJUP1YhAkTORQ;WRmg zf3*t2K#sipqFj(sx7dn`ONufJG+CfNm~1Sd%os5_T%d-{7o<~X@=XC3Mw`iUf?}#} zAOSBB;R7O=fy6DAr2PDxB0ms67(_%&juez-jGJ68=)tcGQox>*pPrtXmtLef`JCWm K#)Qe6gu(z~k!4Z< diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-39.pyc index 9286a194b07ca7b91b5ffd22bd44996c4d97e0b6..4af6b16386c1c3cd545ffa102395a27915c35d2a 100644 GIT binary patch delta 981 zcmZ9L-Afcv7{)vM>3$fRB&Kajp|Q~JhKiyTp><=CnNh-qoTl;2I=QnmzB9Y2C{dQ( zcz5m!ycg*r=BjSHtGl3^`474dAtI>r%vxFt`*wZjHwTY8{>1VXn$kgB_axTDN84DrxE zD(|P?CB`6*``wv!7ROy>|8p!62vQH*B!OGffciwdmL_bQ^~K?m!{>_ zw#w8D%G(4{);vKqty&Z-x^O(xuDLWRzqK{ktbEii1}2rc zoc)uHqj`$~GlJNH=4pgeQw|1yzn!r}6>CfWJn{aDt;!(F8@kIIDsr_g4MJ++>WQYu zc|H=vTv0U$&i?~i_V+tlBi22%Fu*i1#UHE?uwp(%0{VGi3g8Ms%F)O(asD9g)t#!K zdGrt?JygiYiPWWh{NOm;Az_#+LGoZ-_U+EuNV^07D*TbA-~Zh8iw)wXd~H!!>nIcq zn{-hKgVS`+YzXBIr&v33pN#f6%|J%vYR}%-W!0m*Kmy1B>k2{Av$;kUH=HV;2%kz} zl3~0Xa{lzkaX9G-fZ2DOvmAAy^%Ou{O@u$qO{wKJx}QUQ@wXFt!uFQ@o||KqoH;Wq zis;9HC@=(Mfl(k1;D1GzfC(TBcK}rlSO$0MHyj0;!@#dME2yX#Z!1w)Y-Wi#9<5{-If5!*x zHg_~rUKC}I|I{W_3_=;C?!LyDLdb2djD4Q(qZ-u*HCrE;WLw=1&7gEt*R77_=z31_ zg0|Ue5S(=A%xmucSWIFoJeHW4vtT$4ECDqEFWfW8u^iFXlbwFAWs(66d!U9uPNoO& z@w9An)09v(o5jbeQfg8%;VH6 zD6jt`Z*gg|%51(eSuxK+4*~(807QWjAOrY^X&$%?_-mU+ysbXb5Zq mTU?vUuvs@hb(WocgUW({7pisJJxkn19i=9)3f$*UveiGbHo(vT diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-39.pyc index 98658239c24c23b543302ff95bab72ec129e47bc..ce25281e8d907b1ff2698927c4fa05c7e82f54e2 100644 GIT binary patch delta 2976 zcmZuzYit}>73S`)$GcwJ@iS{Dj_fq4lZk^J$8Ma2wy_iEMe41CTcR$dliA&|J$QCz zduP^<7UD+ggGUgdmy#xgR#lr+ro74&5Q0ELc?b$ZP^q*NngrVZh*W{7K!OOV-0#df zF%m2J^SS4B&pqedbLZ)2*}}6dsn^t0eL()ERzCG&G9K%AuxHXK7(G+mbUkO>;BL>b zlPeVr+jD!0bKaz{#{SJ%MyyfBSf4+mBqOc;(wyHSAyeaUb3(J6obH*9oe^J&PqEuX zW#Xaw+oiZ5|J;a#IODgAClg=aFf12pB#60&HO{eEU_nCDa+dD8n#R{j4qp%0E9|P? zksTlh0YegksOxdQ7gSBzCTCdIq8%CUhcbECDXIJA-(mne{dcS8Bi*A==mOj+A(PB< z-Of#Fwq7vQ7~i)j2vtT!eX5b|72l}&Oas(;I{?-TjPDaeosHsSwTIX2mJBs|!)vfC zZ;b0D%hPl|p>boHkCE=*YtL=^C_KPdP(NXKT2^-rXh75D2u?ae6hVwQU7_K!#~8Wr zkJTkuS6Pj`)D`rp(1TM%4a!a;;ZZ{KSL-(=m!wkEHl(@_AdVIQ63XwwmhmEYiU#-Q zI7N961Rn?J;zGKGjR>oui;ehCHmqeVEzUKrNM$0E6G1fl0GA~l_lmMY({`F46n||T zWV=OAQ(yZY*wYqcpr}4nsdAZ*HlKG-zD6Tb)t_(9A#4OpQ zp`J3WTP4FSXLh#vakfYDwVT5H)noNz87XhglaQFL6> zbNHOb9mnIe?}O06mO-?j&jwM;uvH~2Ag)@bdOGLIPRUIfcHRw=OIDc#9BM_~o6Izs zwk;D^aNKYk;)-vr_($9I82;zH3E3bem0&;*#099lb)Xjh-;FEwOfCS(Xz+-^V z0#@7sq~0O8an-yNR|J!w^SdvB&MkGH? z`#z!`Vx!_s^|e+_GF8S$@GlzfgptIJ6U3m5|uf-1LYnO>fo(+2+n7*W?K z2C=N;SaRS|oKN}jjkVG6kY_|&&wXr|8u)n6M;QCE|JJ4mt3gK9Dn13jmUypMWoJd( z=JsZCKw(lpoq>G7AKl!`l<$D{5xjq@uY-+K+zNkDvIE66a$I&-Gjv`890oK=kh@$z zd!{PX(@NY5=j*qj2G5ygWl>SS9WxHkb04BnzvGrB))vMo89`;qzQ5#nMxbyxJIo^A zMd{3Kd86TnQofkMAHnz>iS&W3wWqP9V|`Cj!l_>FpBqTB)G4`ID8Ca+bja?#t*P@BODwJw+<_zOaIte~D!__YUzZ5frdpn+& zWWe;R@5>+YA4m=xmf@N9M90mpRJt_S%6=yPHP}A?eOTRS0mYb=bJOML!Nx!jQl`6f z6y;5B-@38?%S@Lj+*0LD`g4jMd@L4{{}mcbh#dl`W43u2}{?(m;tUAG-b7o#53 z*TmVOb?YxkQcZ-lU6MM<4U%{P^QP=neJ&&ZIn*w{H=1|;O2PEw!?NjH#rfq4q3n9Q zdzWOT)ruRZE>IZM;W|cMmlH^`-EfK@;Ran2k1br`1c%mmnpBnBs}6#p^faA ze_b-t@^{xBwLg5;2BCsasn9iT@*6B^R^zjfW;y>HC_3)lpfHVtBz>e63~$oO^Jl=O z@kc}N2`o=StJ=i_kb|07m5$FJg5;}!764{ec+;N)byh+UA1Zm1`_Vj@47?8T5`elG zcQkCs^PnyOsL81FP;vf8zzF~<$*Tbs5`w5Ho=Z0*-vNWNbCkYg(jrJNY{5IBvb4I5 zXQ5kZITI7|Dus>pdzkzV{AxLQEHm3()VXW$DgOs|_OkH1l!|o#idO-Y5)~Al0DhZ< gAhCNkXV7OE$M-PDH))uIJg8NGw2Ubw(gzRz7bBzs_y7O^ delta 2947 zcmZ`*3v3)$73J-2#@^ld6K6NJ*KzHpiJgg4JBjVYZlmHg{v-}{H#JpgOEVqsj&}#I zcQ$Wkoy0&s1yy_mZS#s+8X$rsMOGmJMk*~O6$n8o6xv7>m4Ofh3DD96RS2n+Na3A3 z{!x{Y_UwK4_wKv*zB@B}lASooqIyL|kRA8xv25AFmvi3^m||Y$HFxhs8%C4Qxalh-{AcO9B4?U_gQwv>nbz#PgBH zh7W?d9xy0jpZv|c9fVsq5}gdRjzQiAxKn}`9p`!>ozn{Xl%ax*pzx#KFTyL zW2H5XN3mTPFbb#xi~v3?!7DFvt7vfNAg8eIgFpuuBDuRZz*Aznrj4a2Z%@}$vn{(} z6_)X2O_}k7svjlSWxUANMQyuGrI?GU}O&ZeF4Oq=fk zMTKewMb#P+pNoyQQ7Qx6#6IPkW;zC!ryzY&UDPj$P(0P(r``+Y5f51@(|W#S*mEg= zAbyPXiukH=+tZZ+GuSSTvjvRL($>FkI8y%wxm1JRvb?q5;C?oOS;OHEkjAH1 zcOCxUHX#)rf)jLySEXrspsP z9+p~O#CCM<*!xWkX!gs#N$=1%u zu#|YAjA1+Ct^QSF)2(6mdMjs9Dm#Sy6#05c-NVMj)&BZp8_w0FC0}Jcg})%}>yM+1 zcw@sm?b~40BSD_Nm^YmahA@8&jG%24z0kO2<>f4+^FHa;Y^)4MiT)N0TWGu6I)>OV zT2p*%dxiUrjzPx0>R#CtU=@3%k{aPf=;`q3kAdf+MT8ZcVN%{=b;MJ>|6BTva z-f!^?e-5HCcSCoKt@dMtT3M;EuVgufr*I5|A|DcubjCzs>uWVXk@C4D@}I)^1xmo= zww~xIEa^x;bkA&C%WA(a8MAXQfh9sRxYqNU0y%$?mREW&E?r)}WurnCO{k$P^9vPF zp5OSCoCS4a_4WZ@Y1p0EULA_Q40o>p&Wodc!-vmG(qsDT*X2X}ndpF#HypE&ZC+>d z^HMysvR_Y6f>A0;UbACC@+(Mc$K)+Y=X~V_**aUjf&U15EVhke9FQ~9=067;L*J`4 zZHYutNjXVACiir>axXv`LE%-7Vswt^P}3g zp=xvw{3Aid`4W^`7l1C}331!tQ%(O@{AH;<9uPCz67HIz+Q8bs!TNQ;8-Tw99tFG! zxB|H9-nXNfu}8(BogJNYF)oAs7rnyEweB`)i>CAPdQKTm&dTsvuxW}u0g9&R*Pyjrj%vqDL+!BC zD}(f2z-d4o00YmT5#I!LMuJzKEIGNIXt-y=s|L_4p{B;|_S==38J*`hCUq;ih5s2q zZH-Fv@UVCDiO~q(*~!4bUZ*_Dv=u<7YmcxXU~i_-Q()5Q*^iojqA~Hc)M^ delta 347 zcmYk2u}T9$5Qa6}<<3hE8%-nDqDZ2IDCrY8A&A%rS}dErO>T8BbIk5V;saQv5bjCD z2eF?55F2EO_3e0Ewqj-w4%Kkw$Xb>_ts<&c(IE_g1fy7cz_Y#ij2-Q;du2z|?UObz09DnkUx{sNrw%{U@0u~lQQy?T-HB%G{(11MW6r{>n zt)|qh2LuW;o9jWHR1<%=N!7F8KcQwJi^1tR#l^#%p)^pUkmj~sXl`eKd8*J*SRl+D zH1zi6C*B=J^`>6R`dVn6f>3rvzJ**X3QE)t^bfZwU@Qf}7)6ZDN?W323>!{^yt#%c t1z@@bw;46SV7tz%b##0{TQ|vgJYl1YYpkWoy9c$v`al2LZuJqZ{{TWNd_DjG diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/__pycache__/distro.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/__pycache__/distro.cpython-39.pyc index 9d59f6f0e072f3189b317d343f4b1b752c734073..998b3dfcb0ee7327de4a4cd7248e034eca1bd957 100644 GIT binary patch delta 4285 zcmb_fdu&tJ8PBjT>JaOK%33)&g2uaqgu(SmRcm>a~Z(_%eulL>SJfIK? zg{Ead$)VC#tzElLbc}UfcQtjDrmgEVZBtvRe^h(iX`9x6DovF(q)wY)Li@hs#Br~j z?w=v$$GPWx-|u{{^PS_5Zb`RqNxA;~{7qT-FH-Ts>$zPvr`N84KM<9@RtU*akIl;; zvXx0*7k}7RT(8P7Cxf>FvN-H?l$+?nkNDYJ4%1eG*pN(QxKL1T zA~ET%JsWcPYwfLiVZnpB_c?IMkitPA-ZUT`$VbrePn8g|4v6nD?i_5<-zW!bx6rl5 z{Il{+X4vB(Yucijq5u^wY>lD;3iK1zuiAGB)ocucioV{Ipa{hb>!hq|W&$U!w4?}{ z!O05-+jXts6_zB)UnTLy{h+Bg8EioXGf6Sd9ZiuGLa`uuqG>l{4*v7)TN+9-D3#*e zOiC#iN`+FBXMpty^YdrJF$H|9`$Hy*GNf2YqbL&;?=<(bUO|yJnFvRNzF1;*QihBS zTan>n8pBqRx^Qc$)R_!_G#ruB+!bjQ$ty?A>nY7bDA!+W|AW*ev>X8?C{yAxYPwMK zMoP03T>M0Jr~dJdKU!D!49BJv*o;zX>SE6docmcyvl%MT+7@2h^HDNag^KC}IV$^A z*(W$M6o&?AbG#<@0jnm`pd;BG8TIhIoeS4?acvFG`wz1tcs9um#w?mD{^^V=oQH{MjQ0rcIR>aDU@?|M` zC%E;3!4FCH_E2fVHe58@SBG;gDTU2YCpPfz`4%a?)nDA~*EE1kn)Rr;C#C6xdZ8H} z_Onm9wxNCl>K{t!7ed3z$Pw14A04S29JIJTUdRY^Hajfb7R${o1V4YixMA#Z}VTNq6@f)9xj&Wj?<#V^MxTlAdv%!u38AV^1c;vv|{o~%z z5#Pi?-}neno(*T(^!|gxG+)mnK35~!#FZn`^lVBou}Q~PwhDE@#L6xGphLe%ccCvmFx-FPl~j=VGAgUm?mN_ zQsl8G{ij<)^n1gx+J#kNsln#V5pn9j2?Q7`;caqNxp34X{9Ol+4eyqKTw5jzh;9)h zckOP$Yst&MAvcy#J2q1n^WVvL8|aF`i!7yVmZIC_9RJUB4KJPkwM!jws^C{L7(XU!X1{3q`7#BsC;GSpLQx(=;3!~>T0OKlDW+!?a~J# z?QAJPLO}xZ8G}QQfn@EIt3cOF@)S4>E1mN+0rC~f2t>TrMOW)Kl{a&c=>GUI6;G-D zw`ezWg@_}Qk(GL1>@X|Iv{a?PtUQ`|sah}o%24K|8a)KXtWAVc0_e}Lc0it3HI<` zEHu?oDSGqP?%SzwH2t>EBe{^Czxa|gOx1RBQ&?5ndV9P3+IHMw129d>MQin+dM;2E zc?%PhcpMYH)U1>L1^U zNpRBA1}ZGmR1PFP!7)5daEain1eXb}5S(tp~)QUtNP0qHcMs1 z=iL;DDv2P5EU}P0 z;4&Y5s_}u{II-Ho@h(CsP?FE8S4f#?yg8HjMx@J1H5^pAalaNaM=Pr9Prb>8MZ}NM z9uAQGWTz~GZDfy6i~=aIc3ZwmGSXDs%yUEk{w0^>dJ&hC*P1ArO^!nif@{W!r45U+sVInHEiFB!$21Q!O~W}<{1lPhk4yKAM4}iuZ?f{5w4A4 zyu?8tC7nM0muntY$a7Y@SrZ>x>9o($^mU$C8EEaJA@P9&!LZJ#N=!Iw*n)}KxSICz zaPdE{Y-8RPUQ*{R5p@)vOwgldy)&g{h4=Dt_8vdSo7+Y3-=;l&Meq{>QOM$?Y4mxC zK$vCY29K~`^0DjnOZ#bdfMAGVFTukEj}ROrI6?43g6|OABKUu07qglvy++PdA{NjT eC8|Or&wIAKJ{3QBkMH%H!kDzVKfzNn=F- delta 4340 zcmb_gX>3&273Pj-#v6+lU|;~R*k-&A0kf2CVvJ!Lzy?DDNnn`e8IL`lXU=M?tHmbv*VTR4Po>cON%OjNh(6t!xj_a^c)<$<# z{-U|K$o**BkQR%F+qQ)v)(PRwca^Jnqbn29i>+9@1)4&iv<&WAE7 zRySD-W^XTksuZV`BOU`{%Yb>*osVGQui-$Lv4i_vvSfXe^~;6eT*JD~WOzuM5XwCa znrR-(rtqL*o|vMj1L{kE%4>~RTyn2thJ5sZfrd^vU?I*bXGAm1Y#uMpG}%0j;I(?{ zZi_U*tVx2BWNIj)LC#H7Bg4xX4AmS* zX!bb#=~yJD4QgJsHRnJLYu;`Bfnzmm7DV-!Mv=^^U5nZ`ZSDC$eF~x+ zuPC?vvHWxAXGE1Hc27WGs)*`|GbGw%42cNJN?N#4ak#+MvO8MplZNYErk|VH9ErL5rZGQ zbSvubvGwObt1Rk#R&RS8NVXVBgA2550NHVTB(Rp5d)4A@+2!PY>j2*~~WKJcy}?HvR` zg6#x52|8rs{#7N@yiD0{4ex&_7L$@sz$%jKCdd%8zWw|$;iqE9MH8re@v-qafEO#z zQlM^`wc^0dM?G@);FgtCh1G0M&UhqcVwJ&i9l$|fK2UC`lAYbVcRam4_}rGxPfBwD+3FG-RC$`#d9Nt6A`Veq*#R;5co6-?H2gV$GLB-=)>^=ULJM1@?f zEm;^q74!=InFh4dD~Gfi4;#d+#Zwm!)(a(XYW4G~NhQm=CGtz{K{eewc(d8c*;1AA zKYf3y&`Ezd2T2u-}pfn~Z<;edeD2>&~ zqJh7=shC4Rx&~`2rvsUt&m>c8Z5?bCCx@t=Bp{>FJCvX4@RF@iLqMdy0_CIwoFPEB zC{z)!!=^Og$gMm)#q+JdCEA78AdXy{tg|*J_lkMBrs}Qt^cQkZHCPo# zHVJPoEvnY{^5n(QT6qobwFIz>XPDQgM4Sq36SlKM>$5DQPSj7TjF1H9?y(%Q&DKM+ z#+DuZO4$~xYh;Nnd-N-1Tdi}WD@Dm>66z#)h9D?EIoeQ5IjLq&-MxMBMCR?!mCmp{ z$8I<}DDB3I;)dR`W=;FrmgV=w1~@{>B~u5%em+p()tpoW&t)oPk9y_(My~>iDe2GLdyWM=ayye8*w31NdBVUE7UaEF%|b^gMGVw4`#UhGY0V zhdne*W}wKc)V@R_&O|(^DaYUlT%|F#Eo-qiL8xA8U7bSM`;5XSOaz<}@2P$8tv zAZ;=Lt`U5X;B|uQ1mBn5)82VEsF_86R0dD~ZZ980uGNQ72G3<5iM~R>*2JmBdv{Im zJsktq;wvhP`CSQTJ`-o;GvkX&#!3HW0{W$ZoM~N=I{`oDvBobR195{ zI-0HkN93JvJrvvJ?Xy+xbUw-lXZ=e#3ph0{kXn8MUtzI0z*g!x4INB)U3QU8@ne#4^bKe8yl>q)?{#>8NQ<)rIf+8l<(#UO_b&MTY#sZbtV7NT5=apI zj3CS55xM>1v+e-R1mwiUnv;HNt|!<)u#uphpof4y@zTzn4j~ue#}!(jLJD;R^cn_w z%EB@Nz9pKeHGPw}&A_(-*E%(mzeb}&n%S?%;5f-~L3@K*T!P-E7H8@xwcaNn|7MuT z#&TiVB;R~BE;d;+FI5R~P_|qSi4J+;aY_Z!$!v2qgMXmO0`GLwI5RW$vO4Or(~7% zJo3EkkU{Zfm!`T1wh?@t z;5mZl30@#LOznIga~}U!5gE|% X%C=n!U(lX73#U^x9Y@*w+V%ee#A%yA diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-39.pyc index d8f7bfa6fcd0d85868a5ec7954c9a9fd2051eaba..1a7c104746ff337fd2bec3cb25a253a191d67b6e 100644 GIT binary patch delta 29849 zcmb__33yb+5-#0mGD%1XNgxEm4zdKF(;P>ZOP&P z-%oq#{j?NMqecxI(0?T@@7kTxKc`(quVub6Z?6(n><{>sc$L4`SYKgfnYTRP?^UrX zu&ico&S#k&?9?U7S61L(Rkqky>bDyPe9`9wF0q{jJ^G2qYHsLpQi%P|hF(omo~K?^ zCcwU$yL$~0je_)?n-H=}eTC{d=XmcfDX*gR6@ceza{7!A>9t1uU zA%GCTCjdwEh7#GlX2hUFN#YGBd-NURu=CjHr6WJ0!rau5<*h0VB@}rp0?X9bsK1SX zoml88Ev1nQx%^&lc}Nu7a>)|gTB6Eq_mTp?w{(f^%pY@Wx6gsZts0|YIzR@%Q39b< zf4~zcE)0|RKc>RzKlY$FY6xmOZkUh_gci!mb}GmJlx=5Jc$D8euG9-v$yc62?+zLQ zXTyX};()Vl!de;yLjIxSS=mG!a)wVFn}UuMWT6fj{97kJ(VnF#EBe^7qOVaF)|e)d zy5Bh0o!8m9Z&JTT34{+_pyXG5&!@7f^Yf%Cw>#EN$hqdc!jxpZKxLJvcXtv^oYcva zGq~F%ykuFY7*2%CSwA^Tx`g8y)THKt$=4-{x17PV+PARX${X-4zA&DmMm2$1e-}xt z$W2w6(|7g(8Xz$zi!f!+>5{|5HAXk-02u(80C%z+4%C#+xk6;Mz?&?9Rsf^HQKGZq z%O)bpX*KVk1cQ)ItC!*U>LUF)b=2t(U3|&!=Mz-|APAFSNCSxZmZ<%j}w}{yZrT7X9 zE0yw=7kd36aiQw$xaMze1Y}`5Qk{*&pPyft66+J@Q0nIHNget(bDmsqLG7RCEG%>n zAS6(h{!N@m7G9gqav6$u17ih?E_m48+5Bu;FgblVKZ1JJm=7Ia!DH?braX7i#PpHz z%e~Ex?^9=HY@Qa+8d3U#I7gyJV$DE%hsArXzY!C@wGZRvBxq8CvqY zB;y}i-dX%qQ&|3lJP)!9xr@vFUKKE1azC-53u8Zz>e;AAe#vNHPmsd>^u|*k*0Q{s zRm*3~Mm!?lf;brNKm9Glw>3ZcuaiAYciyUix4bAkvUVa1z`H!&B4#+dSKO7!s340_ zLSd=bqr!GS)2Up!wCT&}LZ~)W9I@YYrsE%utEz%LZDmz=A(EXftDbBDMcm<1+0=x| z4kfH8rHM&(bONgjs#)4G#bP0_oY{mrfkRjU+g8Y3SyAK(c*)_hTF;>ZyP+?zEIgKW z8b22m7Y5AOMn{8LB)%5{)%gJIjiw7{=0%sZVdJ!F4exBK5#ehN^gr8axMq2JLo|%a zB`lDTvw6)cjZj1_n8{z^81%00b7Ok&Sx(-9oJ5jBL4gW7GahK| zbXqshSkSl5CF{;g2ZJHY@2v<~zRG}_#?tlHyuNOLB{CfA;yLbfL56tY)OEm1saT& z6f7w>%^4BPuEaTb5O){Pk_jv^W7uO z^|J1wk>k@{oKqJy(Tmb#g7dH*+Gsi2?4(*0{H$>PqwlMRr!Z3DY0YSk-=_jJJ)CKY zAy-jlS%rd{hb&L|DkFQAZK^TG6~Mk0U>!g;07M*;c~cCsn7*+**9+(3FEho(H9c`Y9`p?Ewi!^VbFj^0}X_! zJ)F0VVOd@8w7qw9H4G@%l{a4DA)gTNzxj$08Nl@>c&vHozGJc(42ebob{9%eOK2X?wbUy$+qZe)v(g@D z;pWAQ1ED)3ANZ^fTOJ`a)|E$XZ=_!#7dLeo+jr=V?WXlYV9ZS0$$#(-@ru)a=WubW zvuNl1o;OpeF+`{bGemKp29_jJQ5B%|mF=dv8|$oFoUe9{6n8k?9?EMKZAb%+>ZY?> z@boi>UfUkZ6?ZysKeS4`4&PgI!NWs@c*eQyk*CCFXZEgq_r0ilzVpbg4&r|2on31( zx8Q{a88;IkX0|$ub~j5yJz9Gx@|S+KjTLUYbIa~QVoS|CyBmu}+$`)}+B)Ap+Ag2X zn3Z$~wcX)X+kv7XuggYJ^tDReg|2`&lvw7eLI7oFR(J}q_9-yyuT|x=EQ-2J^)F{} z%^lVEq1je|`vHJ9l(^JOrc5ysFNHSZJw!>~fIE3OQrk|RGAVCd!PrUT$A^*w%ZmNn zk@^?a4J9wBEH5m;j9|Ka2#t8Mdx46rga!@#-RZ$u`&bY0f^NS{G_Be9Smz{KU?9l- z`RU8tY^FPmLF;FZo8_^UmzS5@Ts3z#?wyu$iV&!=0FOCe?0u4g!n^mi76)qf?mKLa zVDI(}dVLw-1preQPtOye;eg|^t-^{`hRB$3X4icD{88a%@A10x;*0&oEWKea5t;td z%a$9>RJ!x=t51(bH=!ibCjZJ}67RD>{sxd6uV`G%A$nmamU~xX5{&QaJyG-VYwJbZ zWVDhYtDcs%&JJNacfYZ=>tT9U!_dgMdOLZs@_I_f zm(nErDax3ePejeQH}6c+9lw-KO&oRlz4^o5qVn++bhGP)kZ2+*E#=5OWR-a;6b8xo z5mXINCLwD{x!+7CHCx|5TXZpK+=|7_xQ?M?Zj3U6;R_zanuZ?~xyHQ+ye|H=fadM3`R!=Om%qeJPvOy!uhKOxjCtcF;KLwqMF@XX&R8w&T%0f{G&u zMd`Ehn;mGTv+Rqm)vo|8C{%9(8~`{4@EQQeBFDjJJNyK->UBJ^!TlRg9JjMd?Z;2( zm5~wT6-q83>#p>BY2x771_O|rVWxdhRBasCM`-mi0o%%-dA^-6byWVCiMDI}s7X`o z!`CO>>6R~zWr#K2cv_kNe z7f|X&{R|#h?Eswem2UA>%}rnCh#pJ?(Ez*P!5M|BQJy2wiV-BafTqrO$FEBNjaryW zETUhHBHi)TBGCwQ90nd}rZ~wbI*Fg0UME&_!bD9$yWRvSW|xwlnI`r=r<~VLROaw( z_#xURoLM~6Isa?FS)7|<=g`+4cPj8%&hT%tNATQw3N0B2Ch~~V#1$n)F;i+N?E4Nl zfBR;>IDq_4wv+g6>x5J)%F}NzwQ`(WPUScYzx^iXcXZYOO}Jf*^q-ufleZ4I20dD4 zMop~nRbX|-i$~?6He^*`m{MKE6jQ|7o^twqSC!)i*816g>ATXL#6K!da;AJgq1s3R z*i#FpsUolP7GYhalF_UoK%4|19Ga?(x2&f;Dk0*Bhsi>vbO0VJgil|)X{KmO4-K5m zQv+p+biV&4+bKMiEwXjS2GP{H?$lYXM%2XFUzOv$ed^^Ne=I*j(m0XOQSAl|gi1rJ zQ7>gVp&!QOvo#`m3PGr)-X#GOJh4y>d7-2d@2Y|&#Y=pK##+)Pe3`(U#F&#rs>l>7 z!#VO}Yv=kO+nf`Xdw6(M3-B0g4^?W8_O5Vyl}T-TRsZpTQ2SQ3SZPAPDM1w*p_D=& z9+=VY_UAhZCH(Jj{SE-LQ9yS z;__@fwF7{Q$`y9ahX2h@9Qi#_nwOhy5Vc3~t5h6nNErvOrwp-`2{B&cx8AA>PkB+m zv)FGO-6^4)xkcweyFuR50KgYXc){U?lGu@sq6zpLlygME`h(WF0kR}giVmu{9!w-l68xr#_|zr7(Hk0D+4}S5V(@6A4oPNmW(xnj zzi=SP{hbYl49k>H%(D99MIL4UfG0P(me`X>?EZ?<;((n|TwYjOS>&As33~!Q<+t_T zR-(E124P6>U#*04wQG%`cme=?hmt6RT28Y%?Rnry9oB2wQ;Px)T;>LMv=?o~xPBn! zX7GD1Q_)Zjz?+G9!}2~8sTzdR!2pL*WeA=O#zne)NAYw2x(NRY8a@3iktGTcUN_Tg z&Jw4G#NpYI^w-G=QiAb1w`i|Nbr*Bo%ui3f{2|dKNLjJ#g#1qEQ9VUR6Vb&S@Hidl zDaMNddQVT$*4-9zJgg7*6xrE4dCh^Eq?8qxhxc=61k!qmY%x}M?j;^^Ph?3TILX$h zdWql9i(`Pi8B;P4_5O-TP_I8^T)+{J&g&z7Zx)ACjWE5E*s}HNzT(KpxC*3Bf3>fn zrY|0W-RFqYf7I9he&W~vhi=ZU)lHNBf7}fVa_|7Li?#}BHK_kLKwOf}gTnI#+bNaM z&e@>g)`8-0t{IzYfL15>?Af#3{EK?8UC4Qw2>+YW>p%=CqhOa9Q{|H=9Z#a97{mmV zsA+PmNx{2@i7RBvdw9hY)GUlgGd+H!_=ag~8k{&vlnOVmA`G!_juyMKW2*|RJ89Nu z)PLvE3~nDI77I5!IBpW`I8Ic`9JaQ}Acs9UyFKnStOPGk5C@0e3R3O>xD$Za6_y74^GQXiTw`nW#;ou&*4q#u)Y&$(1KdWIO9!c)?|Xk*by-#J5^?>G-N)eUEg z_mk#B+SFO__)PJODCOy}VaP?3X_0!DkcC{n3i9H)pmP}d`9oK3VoN)HNpY#Sz^5oS zqg^?q9J*55P$Pa_=qsl=AwWBFON{5$i)V{_JA4hHCDgKz?&yx4r)veJjw7Zwc#c>~ z&WVP-iGF;JuzA><>CSWMk$qN$`6oM=JWq_0JD^CI-AaqV$vyi_%2AaNw$+JU$B)V%H6>Ra1G1d}U+5JjqMcZ) zb%|)7#hSxYBF~1b@E_|pOGKaQ;~0juXfhA{t;Q2`%Id{4=vI11krYKU#TB)LJ_=Qr z0lWfW10Xar^WMdHV%uSBJWQpz*{tPu0yy-WAsC%l=qtkxxSh15vb1z8<-P6H3SvGG z&dk%n2~TlprSj%;BdmIn>nrtQJxbLIY`w2kWR0Z#1Eb68QdF@P_rE2BtZr_#J%&@$)GF&U#LCST$A34oIT9HSja zV_x`knEV?G{s+KuJ;$j{F^U|ga>Sa97On8E4L~$@RUG7X#JjTqpoO5*5nE`GAWq3i^1D~I!%$P91>O}y~x7Cl>S0y^7Ulxz< zzAEv{Kt?wp+GiX(PSw?q^Ux}>%+2LLm`tHQf3@h}Hby=hdOQ!ohgXYnRyAVr)2fsNT>Vp&w9SyqRsB$Qb&i&V4J3rtfe&7?e~VRZtj=IPwoYtqdo^U* z3_Vg));O7~F*;p-d(=SI^?a_R(TFevI=r-%ctXAJaOI(W4F{Zjm?paT<`*A)r zm2nN>nwCPkNB=fR66%^DWrfA5e5a558Qq9LU%?JY-_I$NB^q zC$ZP`rpv`y15ObpIwph7ZV1dDj>yy|^!Yb{8vx>k6+C`91&||h!DWi6!oA;!$_@Zi z#0Z$cm|W`$V%wEs)48m+%oj(G*8>NdBjf_NdjR6dn5~Pi5*yrH_i+>KSXYbr1COF^ zJ^&Z7S+Vjm>fcdt6Y$s3<(sdjU}z#lO}j=+Q5RHZ1Yj+cO3CC(RUTHMm`FDQT^w}> zblXkhrnWJ;upn+m&AKx9a+By&N27vWuNBo|07f9( zbG_K=PG{yeMUbg<{npK*eQ#EBHYHe9q>EcX@~!o87;L9Sdr@sC`BX8b<2|L6cPaL> zm3jTNl3^u?HU9zq?FRT3U^GBf6uGt1H?ibd2>bJNKI(g-C*-E=0&jm3Ep}t>2In&= z)vy$=Z;Q}r>$h(aUC6e6zD3NgE7c2b6(>?eP*3kJn(H67ik{*reZy99z56K;bhqwu zzqmNjc(G%8*ZrbX7E5ayN?8?PH0mS$ulvb>C+I%gMANL*=sV6cy{7GLqK|lAZ`>ww z+#H2osdv)zDEP5RF6~~l+)9A9u!_sEk5v^)@K(|OgxZ0kdjNQB@5U2PRR@BJ+r<{K znA=7rXv7UvYCFI#fNcQx0{~m?WKB%S>UNYv#IzgdD_T_uPoVCgm$puMfRZl9gJ(ZL zVloj#qAqw)l#PhVgu@|bk7wg8Kz1KG3!CoacoC;tE`BG5uCVsg$IiGQdMTra$H~bkmw_? zH9=SgkUpFmbGwgVvTv=wyFq3I(;gQ6MfIcTC^`zjOD>VNMMcblM$$05#GI8tVj)EAT;3Lbb`R7o1*3HwAzZZZiu zSA^UqSx<33lG5~ok`NW8wKis+*ZV|c3gY`z(}&wv+8!^mX8$bn6zGxpcf8F$e|Kl`khd(Kgm z#ir!vQ2smsONQx;_W;53_KUg6B!w-niIL>EKYLAVYO|Btgi^`yXH@zE9PKH#yh2d) zp}zKY5g5G(c-bQIbGsO07#HpSV?3S7pn3yHlb1&^zOTo=Av(x6rC#=iD9&NEMaQNq z9yhl1Zu-O-(V&15E4=>*Y zcprexh4sa_2V!Iu#x8i-o8l5t{T}^3Es_;7Gp9xBY0)Uxby_Y6s4{B2S}s^Z|Etvr z3ziP;Gd#DcdK)O~(_xsI;;s+k=^cQW2VqKjfQLsRNT!=z$9x{c4^bO@Fx~$*>$Ke~ z{RMP_!%kS~$L<0Bgj=i?UNfi1_0hM)abrz9ka5<;5@b2mYfW0dErzE59YnEiGFTTR zpZS2R8fuc8W|X8WIAR?|N;H&I?laM`nt--ErSc40->e^9x=@(}0$0#A^%0)_DTD8QBxcj+Iwrsx^NAQ_ zBC8Me#h-|c;wd;!KGah^KaCn-n>?Sbl#>y;jm#M2MaSSM(9Qv1TjOId9D1{;Ic7a` zNWzj2$(8hHukb&-{v(=!y>u>PC?&Ug>2JwJ%cvpHd5 zDXvkMxy&EMXroXoqa7ibt(z#Q`caIK#-~n?Rs~H4HE*P`puet{mXrS$H}_>)TxQXB zCP9&zBW5Ig5Dk{ng#7yJ|DnPD28c7!BZGCp)c=a}WFu^w}?Y?Dist-38E`8f? zVwBmPILV zh7=}*gknV);2~r#;ut^&^Jv=e52fyOD=GK4XCfD( z%Vg?10oyR(V3g^o&nPd)Q=A+Q=--lM_ikUHdM#tcPo9c_XDg_sf06ec7M#^krVBAt z7o|v_n+HB@2>6;zf0rW9sb-7hqZvPd7M^Ll*n$S_kMI*o1F_<$et;zD2%R?)-7cFvsk4VD>tamU3Ut8)IzqD z8B>6fAfDO`NX8Mdyxlqgs_8dL^L6SR}lD_n% z*c4x3i0&Z3WB8-7?qC|qY`ZA(&F!mB<2iXT9Xp_->lMmQEcKNyrC(g$$L86&kGee^ zDV%5}ce#HCjsks8Yk6B5d#hjR#cHeF1?}{+`{bZR#iwFwi|_6>GB@QnH2WVwWcZJ_ zkpW}gJiw>Ta%aB2sIB}YV%zMcmba7d7M@E@$@QNF{u@{XcoJxZpRs}XbJx#<#}4^@ z$UJWF-xGRUdzoi;d)T?f)Gz@ZvIa7#^*i+*9pvxz=;EZ#@?4{f{Xr~a{!6;JyE94q zcSx+ZFxPdF{mm+X(J_rNp~OV-Cp!6k7ukXi?hsG3JY-T>p;!m&Q@`h+Y4tiLWkE15 z0CthcjH=UNZK=wYS4Omj57o8mCa+EmtBiiAn;ccwaip9r`_!W<^Us#6-EMRf)smBE z%aA(}uWC!@i|%qzbrRmPX8aBG{D06K7WJQKPJ;$7&|Mkkguc*s^^lY5Rik7O_J32O zwms$cq%&OF;r{ZRsqB8vj%pCkQ#^L;%{Z@=R$N{j7)NG20Xr9d#VSz0pIbCQ-hW0P zY-k+^%HBp*xue*G80)BhFL(JsdAUqk3SGs-e#VgW93rdSwcm0G{`?TRGK)#)iE;=S zlTJrXSS%_Pk-TFyb}PIIT?vp+quhe7;&N^o;JJ)gR1O-G|Gysi~|= z!~uO-rXL?JJ5;CO4S$Ia_U%MpMW7FIiplgq-}-pyikmdfsm6Xc;@^rsG$^L;LPANA zClzz@@a5(c5r_+iws3idiMl>Q8Elch)32;9Q={p3?QfZ45rIvo0|R{+_O;yxn#c925%Rzp{=f4d`u|R&6E9KLA!rj!mL_)Fvyi^H&))&o&&=mbwo=et{n5S9PdTa z6x+wi)vc}}L{yJE<;t^xnHK_PzMQRRj+bwY_>(0mbI(gsMo z>TKd%ybT(zW!jMyw}uO2<<_|h>RBKw+_>Z`-S?!N%Fx- z-vdRmS+#QSJgU5`;8Eay;#R`-k#$IKK2Odxkt6E~hl(sKW}lhjiJA%GUh1e#&&jf* zt2e7nkEq(fAw|+YOif&jK;NuQlND$GLe(f?z%?+ab-u4uNU(%NK{U76d%EmiHx*Sn zU3PY-^rgDyx}InBJzvOd{n#8@l`&=KMk(XIm_>G)tgxK=XHDOXdc2Zg#qNWjS79)w z;i)S?Y=hw#6@=*09(=eHFb9!X?VbT0a8DTKHfY10Hiyy2%OQB_T$wMbIp>sW_8_=k zED07Bj^Y#^?^Sd|53vL|mP2$A#~bJ>E;n^Mh|fmP2r2AjoTfDqDot{T_;7{G_#PJ9s#qNU=8sp%VRyCue3@5w06sZi-sdvW)Id(7?+x zocZ8N|F2NyP?EDnk^IoCw|;T2hj`VQZBWOkW}s5}L)9U#_+E*@tQY ztPuqoQ6h)BkAlxbLHg2mxEzK~aeoKv&&;U4L)9amJ*p`23>?tEmdVR|#+owmtn8e| z_yGcoWBRz>RW8>XDm_$w+O@C_m9|gzsjKF<`{a!&m=aCgVOZ*~r&P%CDKCR?Hth(f zyDQ|mDg9CV1^{z$TvmJHb`L~H-_BAlEQxM#Q|>Gm4mers|0+WXJZLpd3vE{XtIt=kVI; z?iKQCzPv?2aH{J= zP-^&dI}RMpLL%P7Aby-yZc@n1F??i%Eu@fXlg@mzXR@Q6K;k-?MvzC(gi68rm&jG3 znl~gq2A7;5LFh!;G@j97(qs(mWIF;E`2BqnC|(~z$^i>gq*puWlFHuUp70B|FJ zmRzC2&POk}Otu(oH)kId6AfKMv1&T*QsQ8nawm2Y98`e5<}_K%@V6ItMfPl;zf5}S z&Nuxom(yKmUjpvJN4|ST213;ruN}~jTrD3T7WKz(zUS z7*;+J5%v|c^@AIwKmFB+M9gl2v93;f^d@oWu}0I`o~T3jVU~%B@Au{lfH1`jGB&oxCcS2b>)Z3x@;Y zdN&31hu6tt`MkVOF%CQywfuP|h!L~r{ew(U<_&Vz=%dlG=>qn<0&ob%0cI?=WD4u` z^yx)%bU%mQG)NaB#+1v8Vw40iR*=8aIbIRiJc;1g^2fv1%p4)TU;=SD>wYcZ^WF( zzo{^TR`~u@!rVY4iH3BxDowcM>J0t$EwU*c84tP9zFx4?@woGy4JN{Dznd=&obv>_0v1#C+%4IEpr{t zXVh=V%{S2&MQ#772V_gS4dnd?WS|F_CD+&!oue|l_J~?M0w(tY+zznW_}ZEJng`{~ zM%;}sEr~4pVD`5MWxw>;n9P*ardM#(PWgdL+^utV%fK8KC3~YSgb`6Qf@8HDRhOX; zEKYM1ZFhxd6z-Br!r77Wbf=SwqlFWnKT``jMY&jizFW>{{{q_6UL2ieBS73P2G(<; zV(lB8^QgSkavwvLcKYz+vRQlnjtM)> zyVA#_x$V?N`i4C+rxz;{Q-wpBtZURSPn$HmbFxtljIuO9hxW*gZJVPiQYET4SpF8Y zSs^jS+%LzMS++t+!>p+7y4ZTtWvZYy$kjE`>xW8L@b#zV{nj}=OpGf7SefJQ^>Iv} zUE=x!r10*0R+jZ2M5LWg>`M1CtjKLgGG)KdoG?!?9U2&(aE3>@7#5tcUshT}*zl-7 zmNXdQ&Jk-6rZXi?_XW|-5MFaH5PJX53-X$w=pCaJZF^sRZPh6BJPcqY0LMkc_1+id z*df56Mi3wqh)srZ44Cl1YR38~8=<~q?vVGEx^mB()^K|(E+Nr@W^C{C8T_n6`2rd9Qs2pLHd)*+iOc(PiO!MjGA9wdkNcE3qN5 zdRnZ}8SUuo*zSX}wVO}Jjt}>OE$b5p<%Y!ZR1aeIzb*TwaCBtmd%f#zO5C#k4FS0W zz&>lw4|vLh_V5hEsb7paDdlHn2`s71C!3U4X$(9Jym3B;a z9d0)yl;ya;hBhI4Q(d~x951LZ(oGm6f7feV5)+FsBy3!^4jhxVd{pX#$7GKbWQ~lB z!acP8LN3es9AjY7jlAW>h0Bz=6D34yl|@_U&^$$KcNP%k-nhzAv)8y zlYKloQ{Ai}-Sk&q z%W>gDr_RS0G|~1qvJ?WFjMQ_L-@WqYTe=S$HLlUEP-;;8BI-IpSAI-VZ=-`bfWj~qt40Q!nfAf1eF2#-( z+rieSE28Y=*UqqfQ)-1{rV z4=prtvf3)>F_@wY&(hOk*lE#gJV|?^e)E5FNQx&)On4x>{VuyC;>%xkH)}|?_WdrK zr4+{1%Y3OBRiSvVfeKJ%Qr2$z$=~JdA)G9Pw>~Wf^Ys8^9$kTsNAgiB2qn<{&2;f|4u+oskDbnggbhWUGWU*xo;oyZb zSwEa$r3W*lm2V{#6G1dE%Zy`KpJ4swz7RB)@QdKhZtGu3eC6-6!(>A6mc~|!XvzT? zz7(P8AwrH0rdw^q^ZNaCYhZ^S7#xdr$5i3_(VmBpn5Z%<*gM0T?joh$kY#1jKRV0m zClAQrn_1R7jZ%0z=EZ#^gSxk)HH1F0!lh@et%C8RchcMuIpU;1?+!wqr|4{Yud}Sf z8SLxX>ra49{e!Mb>}2IuGv4ud!xIEg#+i1~Vh{a=0-Swt`zmnUg^oT@9@2Ixf{L+o z3Ob4JM?wtsD+UlES7W_P(283pcyIx!okm|SE~7i2mjp)n{dBk(Y}06aRaplfIBJLL zeSiQDeN9Y>M>UnDzU{Y8RwJ3mBi17cews$;W8)eD8G3%v^zHB$E znL=F3_lhV^$nZhxp#NO!la%g^A1A#zg5OamU~02c#Xig%aLlkJ*5Zrn`UJ)6n2-8ud;ZV7`RTe%3884J<(%UJ6b`VRDk zan{4BKY<^*rkC8;DlPh1S=t$I?ajfbo2O;F1w)HYRT@Jv`eX*sN7g-bKg0ShlUt|rE3oV`DwYrYGmZ}k(x8R=<_1=4OEeJ;Z zVW*SU)0REuBqoveFZC*X>ge+XY`xBF<(N5uE$9mL?M1t5@Pwe#PV-Y%(OXnNt0y#7 zSE7U?de%3nq}`~jxT;o_bgIHP1C>(Nv9OrJ4o@lP=qTK&ETi2nbrq1zMo0M#NT1c! z^xIA?u2|8pz*AI&=|pY9tIPsiKvO^k{UZf-lL9~8{Si3hrTU5n$<~XOSS+Cd z^q?@(R{f4HH9Ei5^yv2u?BBaj0sf|ftsh-tbx6D&rFU5RpG&NB6EOAK!K|g$6p_9k zZI1$Q?C~!|$l^fovSk)s6nHPS!nN1?)D|R>YlX}{P)x!S3 z84uMqH2DnlFybv%@SEk#xX2o$pAA^^ z#I9&*Gg%WWXs&Oqv_{q{P1OIbv>J=YH0^cu2%fvbYAzzB-j!CCd_3It@s-y6NI};s zs`YoY=%e?pvr_chD$5%wJY8jF%O@@RGd`_?y;fQIA|puL6z?P7rJkUtJQXJG!PSKR zDMmkAXJ2GZj9^%Kk=0!8;exv&?nBKOA!lY-I zBTXDN)+Os{d6Ko(s!TkCg6(UqW^ylg)XJGQu9-fy*7DJxRzd`%SFf`&#l9$$7e*)< zS#32H&&DIauiCmGQX^+Qq1_*r8x2Miy>7iVHc}d*Qt@0AZ;I}*!77Oq?%F_}?RiLv zE)9V_#r<(8wFP>FYcjEZ^HCa&RfWZ{8xp7icnsiifWHGg3GfWSUVwc7&jRcRcn$zv znh7Mcfu6EcHVV$U*!nmjoOwJDoOmS-a3(KdS`r0eH$fLr(5^>Q{q9xPfcbs{rUuy@sdP0l0&- z_zr?V8|&pM{6u^lqQ3-UZkJ~?;f}*-_c5g*SZg&LzCou zZ6oQ#>oPx|zSpnr#%3T^ZNq3U8y7PNPa(r|$gc)(yxv+bW|xr6Nb2taIdJ4r7{Dvxo5AbF z0Eeh7@+|;@@K6dL=P<`OVl6|7G^sA8x6@_u zX_VQz{x++xn->kWt9^Q#HQmkU18cvXa=Xm|59}rRPe~YZv_|KVKosg zm;<4XfRV6?I07n6^5pN>=&x{r>yUQBX;d3g=qZNC7 zPUT%R`y7>_VZn?v@z;MOMict)w0!fAig(Mpb)M<{ey)`X=NGR)Bm9e zcHL}sv#Jpm(iL}fC*k;f`j_s!GxuYP{H|9XznP`R7{|78ol*nBmbBJ$=x`x3H{Hsg#I z2MkDVQ`k;`mr#g0a3B>(Y0O!hPoWBeCiOYMF5tsKEt(1GH|d9`io(>8yNY8Nh3Lhm zKh?6hk|K@ba=LLJSq%z)If&x*8$056f%Y&!4$wZPZ@teNJZ20?K~NK--F8BYV?Amm zYTXFHYCjB5BLGGLi~$%AkP1XD-E6DXVRYQBoeJeI0E`6~2qvcBsXM>`fPMhipkOJ8 zctWqt z%~gr>^w0NOUAiGTqe{_f8NlTLrFgdyPn7_E{0vz7yls?wVpp^quP?>xF%a1T{9FTY zKEM(HBxcn*JS_sa0AMM=DgfTwz6S{A@EmUf9IG#tyoHK9 zdGpl%cl_k(p67C&3ZeRpQgoH=vaoS8d$ z{cnw5`di~fPjYfXBl_P@hkg4J2V^!c=~eD6F7@=9=uyRERq0A^uNiBW`RhEHpEPUl zB$cSj@&ezQ^1{k8pOfIP3_r(kiDQ@a=qFyNyRXMLBKtMM>cp0NeLl}puM<<^@q5bD zALylO2JpMOJ-vpC z;MngEd`TQME0Dhj@FBnnfX@K_S(iKb zn>eDW-RSM&3;V$6r6W($`%EjI(c@&`BJ#_f1&qZX$?| z;>59u=s;n(>O(tsaEAT##24BzzhqUeBdhwD$!7^j4ORWhzGrf0`>9F&lG6wsdO(TW z7JpB*<>WQ)^hhTs>^mnHC1&CU>Z%N`)O^a66z;Pn-km_}EDWMWD*Zl9|M$hwyEqXi z@t;bqduYmzSn+3j?Cf?e9k=rOD+{lRCag`}y4k-GaV(!{s;xb2&O0r>AS_Nop~vTi zC{!#}qtR8W-EMA|bf!5Q{kH>X575D0JU2ret6MpDqe$A?o6ii8(#g7;P%h7RrO~G^S*`~bjl8Gt#(dD-; zIhe?dWXy(^WuCpw@Xkpfj;NKMvTCo72}!jF7anNJMe!&y3^Ou5!pm)XyT^<`r?~+4qnM`*?8u2T3_eWHj(hnkk6P+eJedCIJ*Kpx*t^=Oa^3jl7bI!^ z_=?Wrm%8$b7vy9x&vBPl_`J$*y5xQ$(-*{kWvCw6BO`#LK??UX7Ej|?(u(S?TQNs= z;VJnM#0AZu3xkZ-fFJ8F__oR(h6L|wzqg_|R6mxP;$0ElWU0M>^&pu1hF1vTNJI58{B zN=fzl+v{oyYIz1C632{T-m_{A#HgVitaFaLx~kaY_vX0GY?M=hlThhj7Mx$FF+UfV z7WvJ5hi8a~NaOYcRTTi+trB4`y85~{th83WDKDcMp>dV7UZh-8oze>J!fXlhjqk)y`6mRT=yiQJn-e1}xz;YYX=*QK_!X$xg8;FJX<*SPD5)^b84)w=dfU0_ z@7;Mws9sN)!;_?{QP7D1b5L&^E?S7Px_{l=Ub?@>(1qS0WvZRKX@pS3su{IlNS@=G zls|6TIWg>j_1f|O;dccr&%lBpOAFP!gL zs@$Ms1L~90@zEQ{zGZWk*k(Vr+3C#U44#H$bTDc&(|ve?xlnH*u&8@+OB0uy2i4g= ze0!_*tOTrZF7$0|=K|E9M*uTZmt>E2F%#8(J6}%~H`)*D*~zz}&R&e!rEFW=y|Wfp z!LWiom=O+NrSg+IxLCs+S8;WDm4f^_mZxHkVK6f=$tal(><{r({6T9jL-t&po3H%u!*vB5Y%lK_>bs2if0WdCP+k@5VpMx;O z1;$f@-$5n&XI;;S+_F3Tm=iy4brHpFrIi(GBWkb&K1i*cn8G!Fay-58_6D{WzDH)K zBZQ!73r7+NM@QK2Khmo0pV1YpmnnP}PlyA9E`>StoSm~{bTjBijw^4x!b3hG*l(}h z(YBTYv^HqQL`1@-A$T_)U;@BIfXM`$#Dao~%8DAVsw^l_)9`va0DIv%c$y2qkWHzcQ!W7gP;lvbGR#*6`HLpbi;JrP0&nLMTSInadzoBN1i?O?cweiMH z3j+U`S&n_>6K{#P>~4E6cORtpMKSu!UXfvM+pB0@2`Uth%?N)~w za|v;}cofBAYt(D>!XS<<_pC-Z<=E5e+KBJ$vbycHe?lp!QEvlq>)54U(rF5ente_5%o0INFn9n~dcUtLjD04r}C+h5U$9orjJ zY>`;`y3>Qb@wp!24L!4`Oso6jbDiU8k%6_P_3{mF*4!h^@P}Xi+$?;pyu7@e4As@X z>%jEH^VD9A1vqYhd*HVe2<|!9npO{Q96Vu-U{U`Zot_2w2Ef$C)7J!O7EBOORJF#? z7;)fbb)Wt2q;Ru6`Imk8wE^NP5K`Cj^*1ax$N%l@&;IyQSM=h>MmC`EnOW^(y zxXq&1*c?kzCHw6+Go+AppS`(WjNvFqI#yM2p%d@(k^o?-7?e|^P4UH*qbRnjtnfKW zSh3Df-Wgb1syM>7TR8Tfx7J?Pgr3z*^k>Yz6JMyjp5^1q$agkI8ILGQ)=hu={y6a( zg!T5n6%0Q|Eyh!v-4*15N92#n$~YKzta4A4!W0>kgQ`KFLTls-pYbVmPyel(=wi^g z8H2%+<*0msUpwZMs)HY$J2M8`FL)TF6Se6hE%dg)Rm zXxvrG3sY(5eb%z06HjaY{L1BC5&%w9rEs33fNU2@XaVI}$TDJOezxwx&oV_1?t{97 z9`H%Ce_@ zohj9L`@q>xyZ(39QTrybgo!$6)JUia+H*ms*(bi6G>26V;gth!mU&D3Cc0v78oHdg z<=!;~C8Z^mhPZlcC2Y-rH;(bfi6qfXsL4_<`B}EGH?N7eANW4AUzqK|*-^7F&IlF= zPX@5Kf>_j)AcmJuHy^0}`?L_6ta_uGO1~*JW#-AA@k7SgU!5A27b1f+l=;teMNfjg z_lFL#)2V8nV(w>%8Fk1&fkkoJh zR)+T=s2r}aZ)O_>+m@3Uu~C&&AMKDS3Y9vDnmo{nNEEt;V5<%V*$eApq=Cj&SO3{bf$<$a6$(UQUWZv}b0FNCo*YT8oukXZ?QSv6T?-4%D^13cM}{1fC=XtTNiczKA>Q#=*_*JzmXWG<+I>hrv!N@MEet?h914XASx3dSi_Nqa$+RfLxUYkgfu@t>hlSa-+${~!(-b=r{%9P1=jyG36;rMsBx z=22GZnJs0Dz=7`KRw3I-J*B7UU;?^`8NNlY>nX;IYxHY9Mcb*Im1fo^%tfA?iDkZq zTzomP%1JCQtq5-Q_$cdNe})GJ{O+T2%dC zxjBI6TIbFc&Go`u@pJPir0V)`$9jDqacX2#If>@~+SM@biYM!ZzT!W>(i7%EpX~R4 z)myhnZ7I=D)xWhH|b(*=F_?|s` zW-q+D_u9pr>}Ya()5uD;_xt}L==)5>h}P=*udH&xQ=oXIS*o1mrk;;x`;Na ze8HcA_a};xu>*EsEKztEMR3jRD!~$yB|M@;7xc^-q;z%YG?<0ghh~VG?vFsQd2>Q{ zpD7k4vM>8*q@qVZHd8DRO|_UMzKGieCR0y=v$Mo`QO15E!EuobE>`anF2_|_McdRR zAaXcx|5qDrB2Xu#q_oUiP^l=8qy0MMB#No6lgzJ+Dl2HK#!q{7CB}s7vN>W$`z#O< zQ%^n0&>ebmTq|iMu9)RDg8yl*U!5!Fnc3Do=846^m^IQlmwsd(4K4CJkUC$Cl085{ z{`fo+CLYJ*7zYLulrB0gK%1ts&9-SV+ka6Oxbq5eFr_>4Wz`meZ}uNF=}Pq*!d4S| z+4xcUqo(GluYn9{BK3`4zg%RChxEhCMZ0tsANHucQfGPpM8CUS*)jl*X0E^!uUSXqiPMX$I;@PasyQuK(rHyiBlMZ6 zsEsYEEXSs~6IW7QRyLM0C=o~<-9s}6$rWdOQQ@T6^RKYQ7x{js(^PmRU2M} z>fCbiY^%l8XO0-3BgnDmGo~*aE5@h0cTN<*USS^&|1_IAx9P@Q}cLMOam)g0^Eb2_X2DOxF6sF02V;DKo?N&Lv(xsfP-Hc2lW`h zQvlBZ>;tGv1AGqPc>tE)w-Ehj1P)b-rosi+s<*X}t@N2Hv0yfPTAmA5gzo6#SpYUn z$otW@uwpt@{2I;tBUV=zfFFQ(~sruOCt(J@FV` zaX`C7zoN)%+@{}C;(_rT2&1qjzP!}uqxda*nA$>Jlj*6~27JKAkvc+E$uuIaCDC49 zT2)2+Ovm-hJ~4j`3lj+AS}Z~r#Vf)3W;E(AsK}%r57S?v=leyWyPjb_q5t9+_asA~ zcLyC5=e)%ky`@?VHK#~eDoy~)8U0?hXq|WzxS1nswOA?AD$zTW_hGowyJ58{Tl{j_#Em+3c zwT2O|SuHxHIML{yS}o2GVsrz;ghip_#9YHTKVBo2xw*WPvD#;JQH>bTHbOtEaP%Mo zFVu)}RxiZo=UnYO`P!@h5b@*9W@DP+Q@;>7P7E)&)cd;oI?<+<(`AuBWjzMOoM7=} z&%*RGRS}+WgxjoOHVIvscg!-6no0>J-P1bIMAOhfE$fWJ;$5gmLgqu9!c(U0CJ z(g&VLM+v3a3r_m_SCrjEYP} z11#Hjli1v!rJD!OZs-({pgp24u;d^>6dh&SceB{w=DH_%9guvBSU8B~Iv@491k5x} ziZQbf{3p;~BJdC0LSfKEOb2Z&F+p9>mJwiRP7)=Zt5ro%03#g!80eyiJEn6si#yv! z_`;0%5;Ys(!I{k>_Yxrt^w}b6#Xw9!$S`#d5frlhk(s)r|IfFI?w8n-K*w!jmpg?= zw>gANwbSq2CEE37#bE0MoeXvH6=?ptp&s3@?hMra%dZ~;Gm0RY1KX`;v^sWT|&DT*(w zEM8Lt!=cX7OGl^g!4w4g?;-vsbI>u8-cwlev{?;b|Ad$|BEnb>q~OU-fO8Ire3hYzj#18wF-0r1-nLg<;ff_By6ul-#N(e7Bm204Gt31#l3P*i#4J^n z)m5R;2WPk_!;3xG_3Rsc~la!j}WtvEIB;;B|mQFAoL(2Sm(c%F2e7vz&n z|3%o}#2_D|Mvf@1e?sSsE`L#M?bkpTj++ttLYqy|;w1T0oXoQHr2S%Z*9I`CcA%7J zkO9wPYwNC;#6!baT6jvLl!t?H=FM>oF^VIo+*PL>6={KQUlL0sP5aD)VtFcWQwTCk zym3H^+FRFKr$&;4~7GrrCayX0}*i;H*?}W~n34`^UuZVelqm(}j<*fmjCroFwEePZv z67%9|*n8g;BgqeZ^`_X|#zk$MB(eZAt1JB+a4J^6YcSH|`tCmo|LAn!Wwpr9>0&fu z97sC`@Cm@h15}-XG=4=GrYb&1CD6L}FF@GA=DxGvx3`v`?}SbRD*3sW6um@qcn08yqnTNfGnuVg8%$t+D?9_p&juqt9LOxIsEqbr$MnEY#X|#_fia5n zxy&rya>%A0oLEX#(T=}2w1ADUt^+en(oT5$Q{t7@4am3?i<5%Xv7;}X5?LhYS^p4Y z>P485G-vd11K0gSTqARMKz+jlVxehB&X4KKz7Q2HcpR1)M??_9$(ci6h;ElIV1E8W zq=^F7fc?}{P1?BCRo)^x)SXTKE4#8J8}>Xjvwgy}uw?UY1gC+YMZvGoSNWyboyDE( zrJB3V(Vj@StinW2Jl)WO_2$!bF)PmiIpul#;{B>xdC=~zZShNWyj91 zg*({Or2nO-KYt@0Nd)876i9t|9Cv&x`d*6t-ET#{9Ldu*I_hPh>wN>Gs8r0vwwcm>o(zvP_;i@3Y;D%!{ zQ#-9eV*dRvaaSKE#%0!i7gH2+E)mV))sImh(uu$RNE4n1%+1gxgQJ1wKZ(gQ8EXR4 z;1(!2fG=S5_2_HWW`#qi(blqtfVMe8^vp1gc{I93OPY z*m#>Lj1w#0Dw+kB?F7_(6qR_N^xx>y$~IFo12msUS#)%x_na5kr*Ju^C^*Y(P8IwZ znDw*hFJhOY-E>QD`Hz@qwnw@8b{a^~WYLBUj$VrGI^`Gf#*92_K#q{9o&u`aMzJJ~ z#Lox80^kS*yXEMC851Qws5!ccE}I}T_2>&?+k^;`DCZin-W&-sh0NtBjA)kEL^nMu zQlIZGuNEdkX=0oKQ|Ad$XC#D2!PxmEEFbjbGo#F@a9m;nP^fumP&^(USriHAU_Q;Z z51aS8vy_M0F}b{bf{m1r0e_U99m`Ljrv&-?n9j1~6X6MY$C6Wxp<%)~wa1ul20x>E zEenis$#}szSCX(+)VFF4z%6)`EJi%QNI1`%gvd!7*BIfyAmVmMAE<6{5>fL8jF-0a z8tFg9$o$cf#S04^M9D}6rpN3kF*kTfXn$#<(&Lss%j_?7LZfR@i?xN_H>2F$03VL& z*aX?V>$oT_Mr+nZ;MoOg>0dbQYXgfDWQq_QbVZ`9jO7U@Wyro$!pM_ zvwiP_7|!!EV|jcN@$MNA!~A1?KwV*CUbY)|CwKVG7T+1fX8#@nZgT=+~gzONdWw{cwuqJP7>|u$%znQ$I1rrK2<@IGq1)AyJsWLryeogGsSER~K@sLDET&=!F%5``w zpSTE3!=yCXD|061lI4}H$w`cj@rO=oJenql4rgs)k%|a8vz&co32-nytUQ;5XKm7@ z+q!6u^{5Ql!>A5SkkOjRT(dmRgiJ)4kYoDc47n%vG&&3oV_8etGm#~MQF-*kEoHlo zEHjLeD>r0_J%N9;l&xe_53pSh07*~_EZrWUq~ky=*)bTa$?IWE0)qPF3vSRHdnpM zXZOzNAF|{#?#1AaIXrTpwcHrXQ@F&^Q`^W<7fb2e4A>Cu(l@k~A3;;u)?A$}|6GI(Gcw*CG16kRVKbhEpAnY-y7A^|Vv{NfS@aYO z+7fOj^UVGco2ZDORiHzbF{YVuTq11)+sg}4(l)!Z>~Exv55_Up|4G{Rcb3n@7NOS= z6K?7v2MlLvV^mCAgc%VQ{EF0_?;=}@E4+l2779!TiwsLyLjuOK)SzuqOF`N)0Jd_- zkgD9!+Vt8Sc~gBk>CjbfZXA>o${<BtpDcn;c`vblOG-~lPI3m-=@l8^-YkSghOd05frY` zF6F_?W&2t`-t>UY1;?CNIwhNnJYhUN(5FKlx)!G~=SL&IlliyuuBa}h&rGmUXP(Si zC)OSgb$-DhFnD|%j{7%E6nzq}p=h*ASzTMMM$_;5pF!30*mR80pNqqU{yvVIg5Rn1 zy;CgxJIlMG7^mUs^aFqF;v_BidaI`4H|>Wyaa09!P3N_7CXEi@u!)Zi9^g?|V9Y;) zf~3~;39Bb`D$SVPl_+Jidq)2}LcSBW=toCJTl8L|WVZ&CbImB}|25@|9W6)njKsYx zPwc-V3UG-r^^cavMJ-GEJzK=&?iD{1P^g}tz8OIdit!$Iv zi-ef04Tv+%@(dp@Q?7$o^4vPKTucsnCg#pDeSEBZpdCkU`!Rf(pT<0E_X?oFk`PPVESvKxol20k(fy5o}*<&NImAiPowF$^m;#nE|GtH<>7 zljIYVW)VUPP$M(Rll~0);z?qxQA^l{sQyszo-AjXfRKfOB`C6d;xV&#W)iuVOQdSh z6xqSmn`xn)kf2n-422RoOidJfkLg>d%c_q3z$zJ;^GiPDr2S&uc81KPNP5T&+5OVA z(#jdKvpaD-hCTq`5G0_5J}{S-QcP3-FilJc4~~r_OEM?=Sp^}BCu!lEemAcr4#V^0=d&=f~Y|lFv}4$gSpJ<6CMZ;X>&uI z(0{yAs&uY25JX2f5LW!+0$I});ZBWQceO$QygSBhd2j3RpB~x|Z zB{DT71${>p>ZqQ(M1DV;h2%~YG39K=SRlfSHu_?RzG0bOK{h91&hDZX6wA|HChC%z z)%SbkO}UZw@w7Enz*R#DE`2d6Y!U7X%q^r340st!${m?}WaHJ{Xu%5@&VFHuYWRe; zYr_)YG{F@sJgo)%5toz3FR;unC|yc>0-i!Txkgv8E%O#FHv~G#WBh6jU2PF0*nHmA zc$vpH2@SmL63rK2@#G4@E-5P=si58pGOBeAl-^XZ}>Hlla zh$l>dF>}yCly0G5xxU&f7mnpg#blZDYTP8+gaHi`4y+?+Fu|MA8pp-C6I!b~%|6RP zpVeCTy54dJW|qizT+PG5ca3W;ZQ7|j&`Ct{Y$JI~mdj3V_S1azTVTg>*;x(;LAZT{ zg>P0^ZJ;qB&%umg!lMRvOuH-OjXfhx*=V!Qa2}%*h7;B1jDE2~t~VstP$%bHiyI($ zpCS3`N||}7vh1pqwU%^#9k@5V;UM-H&@(?+I}3sF5>_q3+o)k5)791T zP}V)vFRjiZ8Wmwyp`Nu;c4)_0%F)!#e@WT*4lTp>tdzI#MKlU*RBHhu6HiBe7O#@S zO-_{}3Rv@kVSMO849??xc`I1H37{EBX28bmG5yPC`PNc)nlVGNq3<|8So%5DbzFIs z72X;-B%2g1Dr?C7urCcqkU_V_H$((a>PB_;q0ZeZZ_eSiY?+vU9GEw_d!RqrDo^Ee z?jX^4gGjXW>j@`D%x3(*B%HEtle6pX2s{PWJPp91A2To#%`$}zI)%W#+h~8IH!NPr zP)`fX1lyrofbbU<%3Vio1-XgIX&yj@Ngomu-O^?&Pj*}L9X8V&d1Y?o)< zX6e`Uf9NCd!wxxE@U?s9=BLDZTQ_W-`QA%bsZW3}73^g0viNZ<2c8m3qRb-L$vZT( zZ&$h8ah1|V6?B0M9k4WCuGP~*_*6wBtlK3=raTYfh!h?TSdYr@WIaA4?Us4;B_sAI z?$wpMWj}LAE%W1EK98$k-z`5H#^P_8>wa*k&~fw4y2T-jkYMi19fPZdBK@)bIi^qS zk^UYmSeE)NDB@#@a0(&8c^X8&3UD95kH$*hqwjn|&PwLKg=uNNsEyq#`!$V-34dI+ z-?AUt*&RnCug>M1MOLI-=!zw!;`>zD9rFz0!yBi*IUECM!kpW zbsi0t=bklw7G5_(lPPF!@*TLqxU96CkFXcgnG+|_?l*FZOJvfCSeey2LeEXqaJO{g z>C~NP4PtS1KtK8-Z4L2(4?!2K>O+b?!FuMfbm_VKWlk0u7SyHF^!YS~b2OA1_hn_? zikxiqj=pa{eQnG#$Q0qgD3eM~5SAQ)0w+Ax8{y%-u0P!`H?{3b#ftryLL=nrax6zo zHDATMvANL-B?;*i?j=!aBjFNpB0;3cB%xH`<(K3Et1r(JBjB&*c$2QXVavsmL7$P* zQE0k})6q}8BFhK7N%WkHy^OA@SecVeOk}6P`-7( zeo$8(3}v{)Dcm1-fIJT#Tu3Cy{aFM$PKX{pb5>u+M}{hVlRlFi4*jT zM=1r(^0*#k4MbNgSU=;b2sKaQiBsV$9?*V;O^2LBzR=Le-&;9xbg!2ALPStsIR8dT zX-^rx!}Bf2N5F@DDbg~#M>x7&mFV*^d!lhrZiPWJmuT588f z^18&&Fg8SCCRw#CIsAe+v&4SsgA9G(xSTwW6%)>%GpdvtW1Woi_)J_tS)0nDX?)*0 zAGnVEis!60n};v-v=j0I8Ioxq%V}{CFzVv~)HCq>$8w4#4ry^pj=0=Opyn00(}#9G zaq$ja-i{ZPwIC6NPMS}a+2=B0h+2X==IC{&XQYQJ)K( z`$~2d858LZX=VT{#r|-GdKH}6sE2(cXQaTMt6##6HU_qTBm2qNL(~;y{oONiT;hdr z@r6K_v+^2Aw@{KY2Lj*AneHZzivoiR(xt=HM!lw6oR?G5(OyXx0j7m5&mZ)v^Rnw8 zcttXpoN-|<#&kbO4d^Z3{K$y@01O|2QpP~uSy_$5U2G)5(PIe%8T`=vt&8G{YADXi87`zhVHG#2Vr=@LVGVg5o7P1 zZMEyc->$G>N<^3N*EKQ2dUf($p3}x8qu9!DBDme14_g_c?9Lah5tl_=Ww;}i1Pt7b z8&4Anm!sPWD|L=ztu8O4+c>JL$XWS(1yl3u{g^;M=rZL|bPZ=7U0C5H1%L2`G}uQY zuTA$M#}$=Tk`oGD#*ysOHw&v+wsZx)5!QMuz9scZlHSx6SRG?E5wV$|p_MDJ#cll@ zN0%Ctw(}K8fk&EHi6ZS)u%kC|k79#R&-ze`)rP{S6Dii9_V{3cWEO&8s_->%ED|gY zZC!yOO|2QO7EV0x7U8lDCmxUw3_JSabgQ4d%nH1lZXHWbWH-!7fp9wajSkjO^W9eq z-KwM2G`R~%-c23msbotJ?r5E8%I2F5IUne6Bz4zLR!%Kr!woIw@ZwHtlhe$J!`~l( z#dF-1Ra0>~$5lo-Pr6TppknNZ<;bex$|wX*ZW<)BSdI0TpcS`{@!&dDr?Dzsx{R)? zF7c1@`RLO~jGdxHuPSfP6Gc;l>bXFGhdw5RWW-+uzVBqECd)Gx-x8;@`&!L8KBFo6 zq<(yMMPF-HECM$*#8pqN-sx-gyZCi>KWos%Z#cfI>1S1^FmEC$p!fBKepW^bA4~>o zR53uA?$Y0C-5!!le^!LX>ZKc8DU^p;(E*j<W#oti{*7mnPO6<<8=Y!!0jdouW z8o9{>j;So8QH^lvjianLn<5G{IiFFO&M_`sINJJqtBVnttBykz=8UlxHhYLHoa3I9 zH+CG|NCAy>^s8g6AsGlf)cY`h2Z6aQJ(2p4bm_FQ*8EyN;&v|tfpGZvyRW}Nkg_(;Dq&Uz~57aq@s@s`v4C!*w>%#J6up?gp~xIA6O zy8uk?mFRvQ`T(htwEZjo~>-D9rxq1d7m=h4qZm)7&F_Trd+ah|oc?JYzV zb-ER}6ADVJRt`X#%x|v4csm$2t($KRivP|qZJia7uz)k)inCfn^2lUTIf*vy2hm^ZG zZgIFByP*P?b_%R%NlU`730>bMmSeeJMZ@0aE|$*4){s`O5^V}hQ`1p<1^~o^n5M5T zwkArezTTWDwgyXAy*Gn9XHs3n4Y;IjKDDNQ3h~c~22&4PfEsa!qbt2uMy=DB6oXD2 zP%dM9StafBO-BVE0E^g8Jk11AUOdgg(*$~Q8v7`B>n$#z)f0Vitkf)&aB$B837K`0 z%S%_+tFn%U%9kIN(OeXjQk3DDT*fC?DZr^Nr|md38(8L`r+fzVlhVOeEBh6Aii_b} z)I7XuR)D*8j7$Uz96h7NN}tyf{iYTKJBG}J8e(P2xWcb+FGNweJQ+&hLH|XjS6}6z z0ljkzAS;f3sl;j@>qTjaOP?yS`p3Z6I)S!Jt*IjAH4w{d_9l4BG)w$rfvw9dx<>J8 zYKFVO@h=A@^vtV*1oD_(Wey{Js`r;#b0>a*_MEK5$t+su6qNJr>)e*RK@Swh96`lL z0sc(DxG;DpBfg*N1y@;%V~?S{)`jFjS`GEym4t;a=%l}h6QgQexXUEV{<2p}AZ@wz zg>?T5!pL!?xlS;%!WuJhEy%tNox~O>503enMKSNv?gZD)Qz4NALd-s_EGlyJ9TnCe z+Ch{lxIT%ZSbzrrCZM0|fcH~&+*>QHjph&TP*vTg%F1-tE1g+o-Poxp_=6Xmqz1za?X6hZ)*2qx7c@%7Q;TqSWfxMMgya<(4uCmhQHf}Ol zA6#WE3>EZQZDq*YxJh^2t;TAiH?Fq4p;FfxtA)IS0?jR=MWEjrYk_EXI}u-ckm6Tm z(^H-b()4@{b#P~}gP5x+S_&3yxSBe+D^if9zrEU;6e^v0jg`?y0}<`Ovb?5%FOl>l z^9mEL?gZEF0?>vH`>rALeK(W-ySR&pd3G)F;U4ZY%U&?9x&C>rRmp!*s)fF8os}x@ ztv}#Dud@n5^h~a`(&T+ynx~(twXO^mbX-p;w=>GA`lj{P*igZzD7e2qzJVL8<)P9S zH&~gq5AgWX8yw#wkR03*iWOQVWz8Z3-h{Dk0oV$#4d6C_I{@wmxCh`~fcpTp1KbaQ zE{*mzYh>@)nH*Sht@UAyNkF=xiKi&lwb|+yxb-HhyJ*I%lUDRPXbn_5zKZ07o2|t& z_?&7-lqH!DRXEmp7#(n^eu}J|Ilgoyp7{6#P?4XcBqd)~?^9@RPQ03n_qN|+2~qn9 zkn8~134m5=7oHvk=!iZWNB4OWN*?K$F9AdROzDE){rZe1LJQDv*W|z1Q1L!8mfW`M z?Ls5FDoNih zRXK~~VZ4s}b_3hDS?k4|-w+3B3ibgz zaO6=G$SdBLFlxT_t&Yk=e$Zz#~}KC8##r$J-9+J{NJ zpBgwxhNrVUlr8d^Wh3_qz9?oBK6#;g>zMWVs@fae{B%-ObwvT+jz`|UicXw6`se$s zjJaTRq_7}(wOze8W=oR}CXz>6N(U2}O?;`si_|IItw$Tc1?9e_>SfTtllQDEaMgB; z{-_$$PZ=N#BPf5r$5?pQ_3rzvEuC1tnEU|RzX0$$fEyJ#y8DBXH1&WrxWgM%lt*!7 zL)P*sG=5oAFx_weF{x|iROy}wBOS|Sdx@gm(xY` zF*4BSL944(i&&6v<+H};^NoDM-0CUvFH6D1G1curVS9iM051`6Vpq{0OTZt6qdq7* zh`O8#cmzK=g=pi6KmDH#Ivz)rw*W@tC-qA_)$c!IZ57k>@*P$yQLH!auv(}6f;vxg z6O1z(74-`{tTwe+o;pb+@jl#~Us^#Ii~k9gHxi(~{z#VtM4&e6y3f0~K7z?mgdv;kF6HkCyO~9;AP>IcE7nFAf*bFcoAQs)v#uMUc zH4fl1fINV)w3gXr%}%)!wFcwOEPzLJ$49M^y*Q&^g%_0o$TTZIo(chO0=OCARsc#W z>^UV{&Ee#xlT=`?5-OfSTR~2f(65Q!)%ZF!@?v@s-!wpf0|oKcKS0rat89FNmxDg-=?>6D78sIYg%yH@b$E*=KY=+prOvCGWVALYix&~kY zKncKh{nBGr>ssE=UX7Xy@pdZ!!dZ?=)i(TO*UaGxJM&=7LIrzJkDWBTaCYYG*4byX zGiN`}-W&SMN`6HmE<7tTe=0)Hf81Kq>MhJ`1uD!2m;c6H72a9xq19?-*}805wq?t*wUV_m@&!JSWXZDSLy~35HjVKxnr-b4JG-;) znYATVDuSv6ex(BLkP1bSijxY7fe>KHA1DV*C=+fcKnP=QLkLAU0^ta$6nU>_M_S4i zSLsc^?;ZX6_3PKY{_kI;n_iZ}N+eR|fq$vRKfOPETV>;Q9Z4fiJ5o$DEn|W*v!l;Y zb7`8f%#Q4omCQd>sg*4uK|_zrX(LX88G1qtN)b^ki;;Zy;?fd{@PVbb)pmnxwg^bn z$8a9j288ghmY!VDgKRI5(_Tl^$E8)({Jv$!BHe&SOI$S8_@g>RSS7**KYa-7;;%G5 zy%uG5=^i?@gE52I;emA4V3uH5KdP0^k}!-2e{uOA0(;S@kuPtq=J&7I7!dB-Fo3+& zv{niXqDenLyS$3;UU_FR8){BS`}wivA4=OmJ+pZSYVJfbfMgF6VZ9$mqe#Yp*kuW7 z$)=HGDrJWdJZ8&K3hD?zpTnQ&15)bsNemIfZ(Y5i zjs&#{O}8j4*7;5-x=9ItYjt%63Cr?$4y0N}mI*Iu*#lcK)Y1?lfk~!h5};9 zW>Tk<^0Ay@QR2^PS!xpgSW8zm@oCdq)(!)abps4ci}0Fg6x?)0H|`;&s*#GYIrB^g!Xgg+WxA(M)vWo2d6Fj5-5 zPGKbE40UaMT8LtEqVghDlLUH&&9p!ZS|*7kt+Xyfy=s<*OX_J|3ONyAR$(S(gr{2< zu0#l@)iqEhL1b`7fyN3bKizs6tolOhdZ3kU-9Y!Z4FJ8p4e@8&8fHkOcjv&a(b3@p zlpP1(l?SwRR;NWsP#xCPluqqHR(y&7SdQi(<@@nt2N}&WnA!H>fRvktnxYnjiQdW& z2+r|s2MTEmS}839n@@tHb%jwy0g~gIq8kaqXV%o!kOeLZMM7Q4-D{TBk!n|Bs?5+q zXwga7<+s)}70bj@T)V~XO(P`i+F9BpDH+u!r(Gn5h|9>9l_DiTio}4-cdb<;V_FKd z6vA(AU$$b-E}n@K|7Z$6bC!tlKeg9D#@}miE{abz(rF{(#@7^U9++E~l`2|uxs~dN z4D>m<0Zyb(o-knN10aL%w2Q_B%5RBP!F<1rEsv5~SKmsR#TkK|JDXkb%Ri2-1)Ii> zoj{Wv>nllQGOe?$>J}Nlr(@9^SlHtHOC5e`{*7?7MB5UM@jgh69=?cd<#wb)J z9P|necShG`lwt*9D~Zo?S;b0blr-%GGg1zu(?tmOw=6Rz;n3N^5!c<&R^g{lV^p;a zM(QxeK02Y~bf-h_QZjKJCaOZg2vjL5x*&gaeRVr29|pHmE*9RdnABzFq1CWrnkNhv z-1Ep2F=Aq#uPO^Ye21-hErle3bpK{Xm&g4T!`E`b-hZu&Irg2jGn#5yj4Ytd2T z)TR1i)OUm6k8Y@+A!Yq@$h=-fP0}KuVl0!&7$-8W$pW+&dkZtD)HETNVaPwD7Srf) zO3Hvyb*f}?SrUTUDC}QFzmid>=J@g~=29M?s?9>y$UM;!Wzh?V~@DDdH@!sv> zj@~U>Hh3TK@IP+3w;pdy)`aByK;?E$p1IHB|P9}R%yhT3WUgv#9NFze(*DRWLh1d1gdN0fgi63{= z6~5kETlFdi^#YQ=BC&z+Q_k`wmLJ{Pp`9Bq*sn z20JBx{`_FOw{Hl1*k$9;gP_A`nS@;eUlxQ?XCI)blx9=|jzfZV0L$J)%zuKxK1IE@ zFRoY$E9E`=tEC7(xc~7PbSDg17+lz)(WxvI$J`Fl3_QD;0)}Pm3sn0ONd(kL`3bl@ zuNJ7=|MT8maSC=JNMj4c5M-r;jWRiergeyXoZYRKPpV4ozd z;$Mwk(cFaiN+iu_Qo;hLOQQ~sZatEDUQ7!*9XPf#Vr z=md0@d4Rx%34sq^%4{i`ihaf{7MWxR_?2YwdJLU}45lUI^) z#9}=w_z%e5N)gS9*^svJ_epc)O5nft=d6kL%ULMD`05@>8sgU+X=r#8reSrcjcYqy z!rn%pT$uA)k8F_o@=qV>m9}*Q0-=iph-xeuzN*uSd^;)&Kdorn1FRj0Q&E1xb1&a> zbhEURFTT2!-*@zr)#z(58gQ&po%JITer7{qz5EGzoo^RN_#;Y9zUtanrTQ-5;HW@S z3-t|26*GrK2W%McYuSOWM25=_Vs{h=hD9*40Tk^<7ZN)w3~nFaII|A`?EYq!s7bWzy89DGBcDIecJ%>|kZ6;=>5=LJj!A7pJ7c8ONOmA^doA_=IkZ!!KHP27Tl8Y=;Kn)#>c> zIRu{sGUME`&m;c~61-0BGWkKR@n*EkonTaWVZ+1bH4OT7ByS+W3lOeEP%BZBj0CX$ zlgtjl1(Q=PJ8;1H`kAwqRSqcy31}!1g5?lRTNOb|8*Y^zdM$^95UpDNpcNFV()Rn_?AiuQ zBLC)n=lkZp?|tu^{mviAXTK+YrJ%rf75w|;Rr@jjU26iTo8nqnSDN}18t$R`tkyI< zA9GUAuhD%QxYshma@-1Yuc@6CgIwe&jzf8Bpei?ua5lQ}u0Rhsq!j?Q*%ZCgdH~L( z>I-WRA=w9TNpeL4tn2C$_DnS`K&#rU40rdYJIjQhHONl;89?hH_U@(^Ne_E;a}_x% ztl!%FoM!|?oV{MXj$Pi;o+A|NQJC^=-9>W7(GZoNSss?KlA0))VAt2&LAr#WjoVIM za|AU95so1oM-bK%I68@N3V{2fnj_m*lByb=My|{f+sjEeduiKtzz^4!vNzlFSn>90 zGKrEh1(ZI5KRX*BSIQ<7IhOL=rNk#x9UmP1KU z)=gRFtYF6xSoFyq>+^Wd997Jy#@UTK_N?Q6J7#Ee@|mRNXj7hqp3rR0UfQw0lxOP; zdV>1_WWxdj+u^Lbwiev<*R~(wxvG_zm#G%z-f$=`N6jS9j>2dG$sm%s$TtCa7V?n{ z3bH^BC*$#X*@;n233GO(c1tlYj5$t1RxN8r*RE42XP?zpw(|THT$|@~3-N;B23=j7 z7sQ;nA#0|iJ32;xq;BH?_X}o1p*F0RuWxMd=&%?s2thC{00Jj9bg<@LBn&--Do!Gp z=CV}XE_mnn>RJIS>kj~)tnUYWpnlgPFFdH&THn~%@Tf*-HJUbsIf38>-G}>^Wqi%3 z9#0r6w7FLu*3}t9<2ecU={b|sk{b6M7Y{Gh5)=aB**M_&wx!N!PTG0?sHL*;hT;zH zb!K!ElfpZe9u%fIG8|FEit?Nu@m$F8gK0jyub~9qP zHEacqqQ-TAHH}+GxId%k=yN=4OrKlGaDvFm5VGUU@GO88V&D{KtX0dj9mRBDzwU0V z-o0!WHpARAHUp1kOXMxZr&@+Z)tF`B&aw|1YgWXrTJgALX5OwbSo8H|J7)&Y3>Gb1 zk$h+75K!*AASG5%j#!WfIUs}QLWUa@+_f2b?fe}fZ(-4B`2=`3t`H*4bH_)H_EKs=VkD^n^EC53Oh=c;0xj>j){FlI?F%cc zkrp;qLNgZ%UE?6tAUUB36zaHhh9RRAwjdwNOn8Y(C{D~&;#xD9@qB>h3`f+$1hwYy zlzK-p?v51-KRr6tR0o1(_qLXw;3XL82y7Q}`xG;5z*K_i)_`GZsjv~CpAW;i`HYHR z9LThO5jq)GZ2PQ5!-G-q?Qh!z+tJWg(a%d!2->>Zm2_em`*p(Gm)I3uA={yf>h$PX z30GRM+uH)$ctF^FS?b4GGS1nRw#r5BJG9Ix>Q>a4wt`VOZqAt2Suo)AhH1{gua0qJMLJ`adxdiE8C*Taj?E@0kfYS&^az^OsX2jy`^4H#X z9j>bd2Y*`O5NV!zZFe&X{0mZzeul6Gm~;n1Jz>x8FJbl9bmqK)l3aEyP|m)6O<&U_ zCT5-tWz?cj@Z9^i5p9A9O$a*?gk1+7jZFDU2 zU62kVXFUrXUdz_)@5~;62$(fg$*ldu(jdx$Rh_`2eF(YeRDd5x1BCewd|w(S?EVAo zn}$&17{ZZNbivmr2NtDX!sfd+OZy1Bx2p*sXSSEEJr4TaP%bhh<2Yd-cRegk5O!O4 zXW=MFdCsh2z^SI=>~*<>{qJCzG$o`3Lh8{SEuIlN-2v&;N+IS=M);TRK=Cw&hb4+m zBAg_wsAu=a2^^0jeBmuo5M!Hr4^&Nkl?uf2i=OVPQ(q;Aa5naKSBZ&Nn_`-zZs@&% zNLpqyN{A|6bnoFpDMHxb;mZMamC!(cW1m&AnkWM5_p!}=RqWZm(QFD7Q>rUjbALdx z2pi~ck&=Wh_CM%}g6JuDy)yRG{$^$mlvbQwWhNbXKUvcH>pZbL!mSdIF{Ip`m7SONtLQN|V=OX8Z6^ zLuu2^D9?f?J%>@o0eG%vs#X{Tv@6dJt~`QKyaNQK|Qp-7br?7~QdTx6e) zXyhD|N6Yu#g|Z(2@Ekb-Av^SkKtR{O?3|$ra=(~v7gJA+4ia*Sou4jcf$^G}2T|!E zgdYLG7sZXZ9$qMn4)h505=tHx*!)F^`U2enS2 z^UyVbuJBVU(Oy(W9}xDFIDP^FP28DM?2URcnD6e6)G&#`|_)f7Ars{i&Rok-(udK+v}UFz7$GO|ac zs6V8exB||6LgRVZmWrWBNP0KUfy;3zi-vK02g0pl-yT1;gJFV8| zt{uKJ&l;X=c9-DSXoLw)>+tPgKxs}`6S*m7_>FKFo8C@dPMx2wB-_#1P;HKDj{5W^ z1mS2YCW>Y)(kobgN>UZ4-ywltf)*Sf_&Q7HKHMoG!iEC@Ruk&=zKBj>v(AJ{3tq+X zYp74?K{5XWq4xIQ0t4?OJE5ttF=VJ#8iGHHj_GZvz1o-+tLv*U!D$45=R%i273j8T z0C|wred_wfN703d09S!$4^OtVQn6C`ZiNu*Zu2ZSdAtBS=BP$po>;n6x$=g?`n#TGT$h>ZHnynIdN-NbAN!)LrDxsG|23Q@FtIFcG=&< zTRfuAVI|sDk7!U>hqi680cUPOXanFr8BePmNt$YAY->h@7YG)dQOizJ=*iL~lr~=I zj>B3+Ng8lq(yCFz3c<%a-G{yppzpjP=$b{RM-L+tTZYZ<#XpSnAOc?L+=suU!0!t9 z&BsWjw1XGnuMBP>kwrkI$iOfi-7=TrD*ikd!(+pdzzP0&^-OFNIHS0n#SM(tEYEjm zQQ-ps8Za3(P9rD?8Uo&sJWGv1Y(I-^Sme2oD9xA#+=uOi8#l$9lY4qW)ua7WEbou1B~5;l~IG)J@jO0xS zw;)_ZxSxF^TDJ!aJ}*or;9}F{vs6hyCelYxei;EP6upA*GQukecoyj-dna0%Bg*L; R7h?6^dywgnRC8=R>;Did2w(sJ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-39.pyc index 37c93c1d9357408d8578a558d7d8a59a3330069e..66f96bf254a9d0a260613e2e6b43438b11d94ee9 100644 GIT binary patch delta 87 zcmZ3-vV(;?k(ZZ?0SL0C=WXOJX0(gqO3u$KDay~uNi8a30ZOc7DB=cEVB%Meenx(7 js(yA+W^qY=T53_TzDs^`X>Mv>NwI!GWl6^5O^h`F1ydTb delta 77 zcmdnNvW|s2k(ZZ?0SJDaFW$&q%xH3pD>*-}q$ocpC$*@E1t_tSp@;`afr(#5`njno anTh%yiA5<0C6o6s)&KxyMHj;W diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-39.pyc index 01ce74badc779bca13a46df30b90179a4b4668c7..fd03c2b62bccbd4bffba467efec7392d222ffd00 100644 GIT binary patch delta 413 zcmeB?m?puU$ji&c00i06^EPt#GciU@p3S7JP_3VlpPQc#)1qC^kx7dnH5=%;pi-bU8laFv{ z18w=hASfPGyYD#9JzDHtFic3*uS*m_OWk$*7 zdrV&#fhsPu*aAsG)6cNDxG*g9r@} z0W!8o6GYg92(VxDK`gLe6er*1JRzzFmqGZ_dGao!Kk(ZZ?0SL0C=WXP!U{t8o&&bbB)z2=0Q6M=UX)n%n5jh37T{qtHJD=IwmrJ1s&U^(oP;%EuG{Goy^EoYL-lg%c-w~ zoRw4QSEtUXERo&@7v_|LdBiee36ViukU!Jg`>|1T9CeB9G?-Ph13MZ5CR&m1iF)jh zbd?BJR1-CwHh`MKvg?c{&}OOLV>?PUd?tkD@*Ng%kHKneXWf>X!@>$Z>~Y_Uop1yL zAi@tv=gDvty)rSjwuy1z3L=MCLmZ?sT19?B9h^f{Plj^8jX* zBhp>wAMA4wco1^~56Q+p!Gd^_Xt>t)TB2kQaz`V$zNRl2+`)#tLK(&tX}bTXKMXb0 z69D!IuAvj}q~WLBC5_yY+58$Q%k6wly{2BiJ2?pSzYQ+QbYc8tJmoz+>b^p0cn}I6 z#23i*!i4FdOe;hg`97bKPYSomqWn^rn=Hj9MEs_1pt^~$5L{j?R%cu#qlDY6*STMh jG+=NQe{N#gWS-64nRdWk0UB21o8pGCh=w`&r}*$M(9GNo delta 861 zcmZuv&1(}u6nA!$ZE56Ci_wd^{zxR9de)DF&mcNuUd}wIkg#Lbi z3J)@`j9gUmg)4cf%E7$>vLi~h-9{827_rGv3F|eRkAGMxgJJxuzsAa#Z3dg$f$d5V zPNelA4mgh85Zo0Iq6H%Aa1RGHcPznli$fG*{9@p($x13ee3=#Ewc$g?imH%(ckY5V zgk~E&Skw`e3GNV72yz5h)z9qHW+F5kNB87TL)b2lIHo{^Ej0bGp6Jok2H~zQ!i>`f z5J6<~y1+h?*}C@RhK?G62t(VG8zPdvfYn4Uc3S#aHZd4~99?JW72?(CSap?J!x}-J zV4dK|8AT>RMZ=s06BIurNNOJI2s44$?hXkm@%ypcCRTuYFOUfUgWh?5< z__9Ubp`bpGUu3IlFh75*MnrEk$IY-$hOVs32(C~Q(-Xnb+!hRaX zW)KQ!(9V+trznx_Cc0kH(iaJ03m%b%w#E1`f8Ah0%}iD&&TC?h!CCs5XcQNaHIa2b z=%@2?a%aD1<9{=&=qj|@Eq#dsQ?7I(Ov_04AtdK*>NI$?bNZi=`otzaMv^DsYIlFn zGD4{~K~@9i+Uog~&z97;scUEEyJbi7;k0xKwg~oAW%_1uUx(P|ZPx2DsG|V_9#HZ= d(HY@$=@r|N^g=K+^F+ndE7lST7FFu>vp+Rj@F4&I diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-39.pyc index 3cc6423653759499b248490591f750af60f3dbd1..8a8d01e5dbd129a10e90caa9da0da8822eab6927 100644 GIT binary patch delta 139 zcmZn>>=WcpSq^a7MJ9wr4|+IyW}UA=BDPA6zdmM zmSk*}W`4!U7`2&=wT6*VY;rT3Dx>)1m2BHoB!Gq#NrDJ55FrI3xZwm3h$T0Rqi#KxrViGIW&rMCqOw{*CEJ|@H$}CIO52(y2*{sU^ijncw zW&ze3Mn>_;y=Sq^a7MJ9wr4|+IyW}UA=BDPA6zdmM zmSk+sV610mjGFv{Webp;%WBGKu=z5p7bBz2WI1*VZbP6^MMfaPWOE|>2}VYf$y%IF z@_HZn*nA#N>?Blp<4*TGq0}oYK^&$wxSs zBbz=skWXgvB(7RTdyolMAi@JktYj&In^R;05_JQq-0Z{6&cx_DIfU1o(SC9due2IS z$1T>>qN4nwB7TrMEf4{AqA-XBGOWlOY|BgDbVg4gYq0>TT~KKS{ty)dkZQ0jSf3Y& v>jNT!KtwQz2%S8G-$@bdUq2AvA4uHdF32pe&rMCqOw{*CEJ|@H$}CIO52(y2*<8d}&&+sh z@+X!pKyo>&DWl=$yR2S}jJlIG*e$q?fCdy9g9y{j+3Y768BHgfa5_ckgG6*dgdC8# z#axhIP{a)4YJdn$kQir3WkITIQBi(T5jRMX6-a1u6u}L=#g?3yoROMRWDZizT9%ko zntE&UInL$Cc1~{KnyKgr(ryDHyn)0@7K9l^rXW!dpemWoVchIYi~*C^^Tz*Q}arS^$RLXGA8e4?6c$ps?=on3-JR1P1YiAAiszSM1Tx0Vg?Z)HANsJ LkqF+&O-vd9VtgMy delta 126 zcmdnOx{8%Mk(ZZ?0SJDaFW$%m*xYC|0>kaO-;#6)b~g%N^vR5 zEKAi7sLUvte3Y@zQUEBg$?g~82LhU`MZ7?M5fg~u1`*640;Hx0WDpX;Ke>lV0{~O1 B9OwW5 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-39.pyc index 45e8bce4dcd24a61ab8f26480960af401efcc33f..d928f70cc8a456f662d799575a6b2c8c52c1c01f 100644 GIT binary patch delta 87 zcmZ3-w1bH|k(ZZ?0SL0C=S}2J5sKnU%gjlQPfkqENG)OlibqXs6wzV k{M=Oi?4r!#lKiyPqGElQ{N&Qy)Vz{n{esGpjEP$-0q3j>U$&>rMMJjmZj%2BD0*v+laPneb-PQV=SI z{(`xC^3Zw_5&wi2PhRFfc;EpEzJ?q9Sr`;41E?7i?cXwGZ$>~V&?)X^5^0oE3)cpR> z>RbNM%~+5|Nk-wW)(&r9KOg03n85W5+LG9>c2_k8?jfuptfRu4aC)Gr2grpD?BgV8 zYf#RJi6o%LR{;%qX@6ZppI2|JI`W5e^0I@9N~T>y)s$l*VpVz1k`dr$zXJD7e?)Ss zoS5*KhRPlj5PW9Chxsq1p4@cT+lF6G=`lP;r4_|9#Kiq`;^Slwdit+e>*ge-`XCNl zsF~L#E;QG|BGQ%+%%x4NFbicLK_aN{7>m$1twWMcXtB9s(s_#X+1uss>gm9EunP|+ zUc4V}A#7{#%QsWaxak>E)_Tq|Qdi`!TIbmVT`G?YqJz(=h*=02Y%zR*)egdQgc~cS zYGAJ=2lb6oOTMk2Z(=BZS(PV{4XgN(1SE*5xo%3^kXzoGyNBFGcqrd^Pqxvus_yI9 XUH~wdip?a}!bK>Uno>BBKfTU>f)=lQ delta 698 zcmY*X!EVz)5UuUlaT1sIgm41MftF$^G~rMxr7Z=iD%^lCs8;qGTecfCc8V$vMI875 z_F8TnS}v&S2k;48xUd(#fGa|r*tel->ciWa-8XOEjQqC!+i$V?`R1JZ{(LLXT3vG} z?YJ06Tpc-kSxPgGPUq-`BK&o|8>Ha#p2W5{&>YxTlZox9O9x7=KXVJ2vl`-K^MP{{ z)LY_5v;VlSLg|$iQyVULm5d`A;#Cj$2+=O!3E^vVxkxlGcQB v*}&frvM}L#x|v#EY@k(ZZ?0SL0C=WXP+WK?L=&&bbB)z2=3^hk(ZZ?0SJDaFP_Mq!gy<9fxH46kY5BMe&y=trlw>j>U$&>rMMJjmZjF^VTXGq0euB)+&Lu_U#K8E8Nhr-!GzN4!&Hh-;KUd~!x&QE_TXd_hru z63~z+zH}fbIX^EgGbJ@IIW=nXCst#@D8BfN#Nzn!%)I!d%97OLsL5t*u6$8!5KTq0 lAX6uIvK2^136|z%mI2L4%t=WtNlh-vFDhaJ%L=h40RZ1rLRkO+ delta 189 zcmeyz_l1u;k(ZZ?0SJDaFW$&q$t0GmpPQPJnW*oPSd`*Ylv$RlA5fW5vUv%UIJ4s| zp7_kXg3^-s;*!LY)FNh}wp*MYp6(v;PLUz5w*=yoGZKr6Q%m9tit>|Ei;8dYr2{$1 z`FUxXDXDqMskbKoVKo-K#TTEESR7xTnHQf_S&~|OYqA5IE8i_Ph^8VXkg1a=vlU3* d5-iOFI-saHF()OpBsIAtzo>`_EGxsF1OV_VM3n#l diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-39.pyc index d8114ef95c8e05a44e6ca866ff965f5a35340a1b..2058f2c328200213cc7be500f97b7bd6cca6563b 100644 GIT binary patch delta 59 zcmdmdg>ml{M(#vjUM>b8$d;bBk$Z8bLb-lMer~FMc2Q<=Nq$;tQL(;DesXDUYFr* delta 49 zcmdmcg>my0M(#vjUM>b8_;J2?BlqG=v0VM!)RfFbeUHSV6qlmRvQ+(m%8Zi9=Q8sF DtD_PW diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-39.pyc index 7cdc25575773d1a31ee6aeb13f932fb41b507d90..563cb8dd53130a24f23aca32b651aa2455212170 100644 GIT binary patch delta 58 zcmeyy(ZI=_$ji&c00i06^EPrnU{t8o&&bbB)z2=M#;DCxIHH+Fqu4U@;!6_KZ?O~z delta 102 zcmZ20y;zz%k(ZZ?0SJDaFW$(#j8UveKQ}ccGg03ou_(o*D6=e8KcF(BWb;MFGi;2v zHqYaTW){80mYEk{l9+yrrJyLa>=sLMX;IOw$$UKP8E;MA$K%hY1~jfne{wCa_+%~K FW&jNzBX zlAm0fo0?ZrtY1)Bk})}p?HM;nC0Kcpz~pH5ZH7_Y$vKI|#qlMHNja%Sj6m5azT}L= zqWGNDJcwWv4@5;;Vsc4-QPgB74rLo*kSS~+f*nX`vJ~+FsauT6QCvxtC8_aX4N+Xl zrA0;Y#U+U)sSq2%b_+~i$Wb681k%O`)?Fk5G6&gRx|}Tn7=i~myQL&SD$!*?V$ze- wxWX+2K}=o{AqFDEL4*{LxW!RWlwXiqR8mx3 z1C7;WEMf=QEedx4RDn5XivWh;Y0hpb1#HSeVoH+>xWX-jKulf`AqyhpK!hTYxW!RW ulwXiqR8m=_1QJ8|7;52vE_W?-L9jlX-29Z%oK!m*Ag`DONN_OmFarR~>sONi diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-39.pyc index 5d1926ea365482d50e1dc6990098ca6bac276234..2d4b8a45e13d49ef11ddcef25d7f84e8d7aa03f3 100644 GIT binary patch delta 58 zcmey%(ay=8$ji&c00i06^EPrnW>l!s&&bbB)z2=rgYzV;`3?injCN6x6+4~3@ z!`pP_+O*hY5ua7n#P*?1<&L}4ynRv86V6;t%Ey{myzKd<@Q-@(23AF>0qCZh|q_e(H>!Aq5W2U;CQg)h$MyC)ijEhK|Eib zhYbjmNZCb(Jk<^0&+obQoqm8UksETGv_ah#c?MS6os8OiPO}IXn&N_c2Thi#acmJPn&5wO`3!x6}mA*TWG~1Bt>u`h#MbZ zcD{x5J#>FpuEhs%rA|P>fqO38JACKNyl3CC=^&F)SH$^zjh@qMiTq__J{iw~MlT4* zS~$CzH0;~yVtJCdLw(q6_n1jt>bq=U8?3{q23vnK&mkJ~m}L?JaG%&Dz6pwMIh2^N zYFeh>?(2{wh5`I5`Hh51O;qHEa*m(lGCz}c`J?=h2if(Aa$8tbnp6d@NZ{l2` zB9iWlim(ujq@;u-6jnHqvP)liLdSqj+9e)4rGST~!E|bjK>6+1wp@`=?9vxkK@`m= zi|O?^+~Ws$yHpj#qZqyZ4=wPC1PZIdptQWlHB^Jt(9~#0e1it6A)4P3@6$nXM}wAS mfUL1D^MJpkN~q31QaeHwwY*Uj)G&@8#ztXXcow*>R(=4+oohw_ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-39.pyc index 72e97cb41256a77b1072080ef375c0e6ca66d192..df430fa0cd7cf353681e7fadc9ca7d625e1771b3 100644 GIT binary patch delta 94 zcmca8a$AHuk(ZZ?0SL0C=WXN`WKpQl&&bbB)z2=107hdYog;cx_!+cP;@>Oaij6aOwd`W-dPfToxT! delta 84 zcmcaDa#4gkk(ZZ?0SJDaFW$&4$Rd`fpPQPJnW*oPSd`*Ylv$RlA5fW5ve|~^Co|)% h$z~kxK(da*5l9~3*u`i#xtcQx$iBy^2PAp9`~Zhf9H#&P diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-39.pyc index 8015e0ec4d235636a974ec8aa20bde040be7525d..521710b12fc3721f9dae5bc0c3aa365c58fe21d0 100644 GIT binary patch delta 215 zcmdmFzQ>$9k(ZZ?0SL0C=WXQ9lVpsVTqP;X5yk2e6(1ZDHF>_Iyj&EoXRyDKfsv83 zU%azVa1;-M3sQ1NQWv4bD*#0akPA|xE~TphH^n;$MG24#R3ZU2(>rLgp_GILNYFRl z*Wbm}XC*_C9MFAW;#Y}&Mt*Lpes)o2aY=q!YEiMiOMY@`Zfaghv3@~iNyg+uQXc?J Cu|6FD delta 205 zcmdmEzR8?Bk(ZZ?0SJDaFW$(VC&_qga+Rbk$1PTmsQBQJTa)KY%FEs2^$hkmGB7f7 z_KSD+3BJXH;DVIgk<>*f@d`ju0_1{}s7vW;z)kTELQw+b0+mQW&GZhMY$zq62NLv+ t_w{#i^;yYKqy=;znD~{YpPQPJnW*oPSd`*Ylv$RlA5fW5GWm?u2LRMkK*Rt5 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-39.pyc index 9ed00d5edeb2b431318368413bc6fb1568156c30..1d0860bf34b0e7b1aa45918d8f80214324632210 100644 GIT binary patch delta 58 zcmbO(yik}sk(ZZ?0SL0C=WXOJU{a{k&&bbB)z2=*wJk(ZZ?0SJDaFW$&KO;0ROKQ}ccGg03ou_(o*D6=e8KcF(BWb#410swGg B5P$#x diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-39.pyc index b3f0fc815517202aee2fb9f30df9eae2bf557213..4337b287cf303a50a2e8463a0a9736df22157acd 100644 GIT binary patch delta 58 zcmeyz(ZR``$ji&c00i06^EPrnW>l!s&&bbB)z2=b8$d;bBk$YLDLWO=ter~FMc2Q<=Nq$;tQL(;DesXDUYFm~8M(#vjUM>b8_;J2?BlogQu{{0U)RfFbeUHSV6qlmRvQ+(m%8Zi97c&b0 Dt(p=f diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-39.pyc index e3f8cf48005636b6c106f9daf5320c7892589da3..62f1e20d16f43bc98e622dd83190d5881b7450ca 100644 GIT binary patch delta 70 zcmeyz(ZR``$ji&c00i06^EPrnW>l!s&&bbB)z2=b8$d;bBkz3MBp;A91KQ~oByC}1`BtI>+s94`6Ke;qFHLs*t Nzo4=tW3rW3ApjJ$6R7|I delta 49 zcmdlwm2ve{M(#vjUM>b8_;J2?Be$fNSiXL4YD#9JzDHtFic3*uS*m_OWk$(l7q3D9 DeH;)t diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-39.pyc index 98201ca75a1346e2756108b4eac452fc55c87fd6..c9d1ec9e94aa1bb04c175af1b101c62573683cc6 100644 GIT binary patch delta 58 zcmZqUoWRMQ$ji&c00i06^EPrnV^pZt&&bbB)z2=(pPQPJnW*oPSd`*Ylv$RlA5fW5vRRO+o(TY0 COb-tL diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-39.pyc index f1997e74665226641ad14b51f6a3d5b2f9a880cd..6161023b004592520bc205b96daf0a15b854c746 100644 GIT binary patch delta 296 zcmcaCepj43k(ZZ?0SL0C=WXO(z@$*EpOK%Ns-InySzMBzmReM-?~cG74w`jVuxc5yBus zf3qq3Qbz75j1Y9}?{7;#p)4lC%a9mLS3cLf#W#%R3 z6qhF5+WekFmr>LRB*_dSj6sA1h%lXO$R)vOG}((QaPoRCiL4@hkf;WTFaQynK;jmU zpMQ|AqfdNDu%nA-ktImn7DQNs2rCdF1R^9sgbIiNJID~kvH%jdI0}mL3sQ?pDvKOI NVoo5!XtFH#0RWi!K{)^b diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-39.pyc index e6bc8711880a712248b9119b624fca70602bf4db..d7e48eccce1f55bbaf621bef837f588303eaa540 100644 GIT binary patch delta 59 zcmeyrhOu)kBX=S%FBbz4WJ}N6$o(Nyp-ev`KQ~oByC}1`BtI>+s94`6Ke;qFHLs*t Nzo4=tW3pga9so*U6u$rf delta 49 zcmeBN%lLl{BX=S%FBbz4{5W5{k^4iaSdM;fYD#9JzDHtFic3*uS*m_OWk$(l>99Ni Dr7jUp diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-39.pyc index 7ba09af8b02a60052829460bcec07418765a0191..4859fabd2e1227c35cf5615a6d4421477c158793 100644 GIT binary patch delta 296 zcmeyclb8$d;bBk=w0Zp;SL3KQ~oByC}1`BtI>+s94`6Ke;qFHLs*t zzo4=tV{>}@d?v=I&Fo!km^4*@8jBP`gcOKS1`*;QLI^}CfCwcJp*s0a&tt}@$p?Bx z7_}x}?d@mOnOxf;zPYAPn2}L!@`QeEpyZx@S)lN(enm$4$$$DY<<&ttH9&+Whya;; zi=&_@zaX`!q_RkVa?1oIZe5U!7>LlCym5jk(C~k)vXh@ocmy={_(WSa3y_rMWXB%y u$%>QQxsi+nx=2>g4k&#Eh>Mwk1P5c0-Qb8_;J2?Bez?-Shjv{YD#9JzDHtFic3*uS*m_OWk$*7!uI)0 zjJGxmcCBI3R0S$8QUVcDAVLL1h=T|r5TOVnltF~rLjY65D~e zm;*>~F!Hc4F>)~j9dL2Nf1u45C)%=EgOu4!7MT>sjbt>)1A>k~sVgAOOkmALj+0kU Ol4JuJ31ps{WB>rQ6jgBm diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-39.pyc index 36591dacd0980db5b6c7870dbd657b0e1d4f4ca3..0cf0805e9359ab34d9f4ddc9f6b6e6482b413d1c 100644 GIT binary patch delta 188 zcmdnBit)%QM(#vjUM>b8$d;bBk=t31F>12E-fER7!Q_m@qWF^h`23=j)S~#@#DXZk zoW#8J(!})C_}u)I)SRfva{A(;Q9{|NsRi+g#mSkO@j0m_C8=nx^lPpIn-onpaY+Urb8_;J2?Be%02KF$@^tiz_i^-dkN5R=arL>SG+DqvbTXrXCQzBSft!K=BLhPbi1<~mpPQPJ anW*oPSd`*Ylv$RlA5fW5vU#?_N)-T`tUlxb diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-39.pyc index 2da481a7814a5cd45f3c48c683e96ccc6602672d..4c89cc5f426783bba14e9fe4d275558cad208dc1 100644 GIT binary patch delta 100 zcmeBMz&K+8BX=S%FBbz4WJ}N6$h}cVI7+}h$ko+5-pA3;J>J*f#nmTj@_8L=#;D2M zx>j1ej0_A#AmUf8enx(7s(yA+W^qY=T53_TzDs^`X>Mv>NwI!GWl6^7RNa+I0D)y5 A+yDRo delta 90 zcmbQSfU$1@BX=S%FBbz4{5W5{k$a<#@GSxNAXiuKcppbU_jq4_7gwKKlh5l|Gv1oa rt!t$qz{tQ*1R{PF>*uDXWG3o+Bo?K(6lIpB>IYP2lx)t|U8w{B_Xr&E diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-39.pyc index 0770e8dd838f07f77dc12cc4b6bf0f01f0be92a8..eabe2dcd1804d0148bc30bcd6df170f0d6353eba 100644 GIT binary patch delta 95 zcmcb#fbq@(M(#vjUM>b8$d;bBk=tEYBudc3)hWm|Jl@CA&pqDP-^JA@YI2&cgBA}X v149vr_*JK$k)NBYpIww$T#}!bT2!p>lAm0fo0?ZrtY1)BlCk-iZjTZG2y`9H delta 85 zcmcb!fbr4-M(#vjUM>b8_;J2?Be%P*$Spw+SEnG?@OU3bKlgZFe-~GuTa(jt9TfN& l85oK{#IF+l+|-oJM17CMq7;{+%(7JdfXa-L%@=fglmKe18(#nb diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-39.pyc index 44656c66b0fd318483006888f3ca91bd8f80e052..633dbea381f4df0c7fa3f59b96c77afd74fbcd91 100644 GIT binary patch delta 183 zcmex&ma*d;BX=S%FBbz4WJ}N6$bH9*Gm6dA$=AZnENb%yGZ{uf2-noKip|^K(?T~W zYO<__t4x$oP-t+lr=wrIkE5S^ysy8Dt51{+MC0UmOYzB5Ekv23lqO%W5S^T1$v64D zg*0Q-h0?CP%c3J|A3=Bme;#a+XMt*Lpes)o2aY=q!YEiMiOMY@` TZfaghv3@~iNyg^)mi)Q^4YoKF delta 173 zcmeA;$N29oBX=S%FBbz4{5W5{k^7Dr=Pfo*CtnLQvs;@#n8`2-Lb#@;Rczk=o))@6 zwR0~n2TS}8JScp!}u;iP3 z-a?x3*5ua~#z0cu5<~`D+5*XmmUar#j0_A#AmUf4er{??W}?1FVo{1qQD#}Hen4eL K$>yJy{JH>`)jBu; diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-39.pyc index 3a5b963d60b4322d5203f54f284dc48176281000..dad28adb4f5617b4f484e21417e2cead8b653e57 100644 GIT binary patch delta 93 zcmZo##MrZlkvox>mx}=ivZd#3$~J9m*%GCl@#k2RF-6HuF&gJ0swdg8@d1h delta 83 zcmeBK#Mrcmkvox>mx}=iew;7f$jzxIbc;X4!_hO|$I;I{-q+v7)#uh^H9aE*K1K$H jA`tPbNIy3b8$d;bBk=s{?F=}(94kx2%lu$@$khf>BN4$@tpL@Kozl*C+ z)Z}tqJ1uTT28JRK@vB}xBR@A)Kf5TixFkOb8_;J2?Be$;(q>F{oLby{asvr uZcQ%NwNv0@WMC))5x+|Hb5m0?6ZJh3i&9*QGRso+11d90Hs9CnRRREB{vI#@ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-39.pyc index d0d7f61cc3512bd31e12e6ea1465a19e9f31047b..448c727fd85e253f8e462f427e94c319e9ebc56d 100644 GIT binary patch delta 129 zcmbO%K3AMOk(ZZ?0SL0C=WXQHVO6Ns&&bbB)z2= V5D^R{oWnqbKZqL^HTehEYyhJ~CCC5( delta 119 zcmbO$K3SYQk(ZZ?0SJDaFW$(l!zxy&pPQPJnW*oPSd`*Ylv$RlA5fW5vN@d9n3?w$ zS8_&TQG9YvVsY`U&C@w9FtTX?wHE12&gCjpxy2mn;#MR96u8Cg80-upf`No{7>Mu( Mal>v+X5yX=0ISa>`Tzg` diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-39.pyc index 58a515ee4ed8311399f630a3140a85bae305ca3c..91c27b58cc25fd1aeb8a4e70773b8c15278bcf97 100644 GIT binary patch delta 58 zcmca7_(G67k(ZZ?0SL0C=WXQv$EZ-JpOK%Ns-InySzMBzmReM-?~rChm01iGU;znmrwKpRD=~I!jqn4WNc^z6=H)a$}WP6 fu!BXC3oK16p&}e05w4`nbW^ARCq&a^0~TKZ&*V9p diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-39.pyc index 3675b45ac66116dfbb1d0dbf27635f8b92a0eee7..b3043391c038fca0d2bf5f4ddbbae9d7a8bec9b9 100644 GIT binary patch delta 1810 zcmaD?^`nYAk(ZZ?0SL0C=WXP^z{eQ1`3~Pzrg~nWP|?5oZS^soev z9YFsNWSU~AA2{2YfnL{SWS`8)CC|eGWJj^NI~f@p8f{kOcVpaauWHS>d5!iGCSb}9 z)DvK310`!sw#l~ga+_O?Sy%=-H%j1$H@?Xmg&gVyK+y`xh#;0Aka)=rVhQ0RUh;s{ zflC+>kU9|Yk`F|HjRFN&5ttALvA}kK%+nNrh%&bflVvRB7^5azTgul* zu{(LXo5lx+L&xT0!#2T0_F& zT7gWcR*;~FV?DBG`G6*Z6u|UyLDC*rGbfY{)GZ1VMzxtArUIs&BiPF`7_6Bc%mQi^ zh6o`vYJme8A`R2W73v&pk)<`5b>*2KO;XkRX@8Zv$!NbEw!jv-z7h}G&eP`q*%Y8 MvLs{kLF=`Q0MuJOd;kCd delta 1059 zcmexS^{$FLk(ZZ?0SJDaFW$&~fsgUl<~w{>nI>-)@}K-cNCXMsc6XW)aq4WaOKyD`EpQAxlJw7sz=i5x4lYA`>J3<~PbSuo;PLJT2JV zY|KDcYO+seN4(?#spDnP0V24Yy9CAw-%y9N_42t)0^@|U2 zbny=^S8bVj1u36MTyU!USp*feNDP{&jbi68|qymPfjc; z;sols#g&|&mzJ55nwOjkF%P1Da~7vPqX3u<5dfKQFnK3esemqssShFyL4?_4J8mUS p8?Zc(xWyYEpPZ9eT%4SmlM^40WG2|jDw8|8E0D~Ex>k@!2>==8K6?NF delta 245 zcmdlhu~~vUk(ZZ?0SJDaFW$&4%glIdvL>^PSc!gaYD#9JzDHtFic3*uS*m_OWk$*7 zROVntZY7}VA{7v!I{7e5w}1wm4;74K?ZFV-{EIadWOx9lBsW+YMD6AhPJ2cHBmt0F zhLaC-l?v#Am- diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-39.pyc index 3fbbbeac87b3522ec606c0caf306cb9eedda3419..16fa2ebdaa7adad35e8ebec710a6642ca1d403a2 100644 GIT binary patch delta 257 zcmZ3(yN#DSk(ZZ?0SL0C=WXQfVrGn*JdHU`J&HFYHK{1IJieePKPj~+N;D@wJu^8m zCmvOJvNDURLY;m_er~FMc2Q<=Nq$;tQL(;DesXDUYFTnhbYO-Pf5)w;sC4o$EvRr r#S4-v$wO- delta 289 zcmdnSyM~uLk(ZZ?0SJDaFW$)A#msnX@-*f&^;^6dsYyktj>U$&>rMMJjmZj+$1j4Ccmi**C GHVpvT@>|mY diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-39.pyc index 15cf4f3d4dfe101c938fb7fe00064ef7aced23f4..4642a185917538ea7fd799dd42e198f471842054 100644 GIT binary patch delta 158 zcmdljd{me_k(ZZ?0SL0C=WXQ9VN$5n&&bbB)z2=n`FSO&6(#XNIxT9l x0f#K3-efH delta 148 zcmX>qyjz$%k(ZZ?0SJDaFW$(V!z7lkpPQPJnW*oPSd`*Ylv$RlA5fW5vUxgFG7ICa z$-mjcfMgK+5fy!)o+3UVaf>-Ou|ku%NC?E{NzTtJNv$Y}2hwS`CR=gHGU`u`;3x-@ n7dU)?T4g!)ByI^LX8=vlEG{X^Oe!tO%+D)g0coC`%$WoLtpG3N diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-39.pyc index 9691a06b2e81879643ab3f4bd55d746b6285efb4..4019685ad432eaf889eec1cfda0f40b433c59251 100644 GIT binary patch delta 362 zcmX@FdsCM?k(ZZ?0SL0C=WXPk#HP@opOK%Ns-InySzMBzmReM-?~%{O1;zsoFX2{h`Kps%N&r*Eile27PoYp{pE zk4urozq<|`;1R?zR_N6N6{X%{PtMOR$jnJCG6pFz0}<9B!VyHU0*NSQM<1UeSrAte zM3{pJx5*R5#3%0&wG#0Jadkn22#D|k5>b=6#PqD9I8%$0A+9Q72Z{3JB$j068A63P YKtlYvNy)|OMfs%#P*F~>_9C%Z04Z%~)&Kwi delta 314 zcmcbqdtR42k(ZZ?0SJDaFW$&KiA}6bKQ}ccGg03ou_(o*D6=e8KcF(BWbF+Br$o4$ZbZa$pxa)Ds~{%E+B#xB*X0J<5MIH;!1)D3lQNqdA(?$NFa!*3nD~7 zL=cd;HCaSV&*~OuYH>2uZg!9;PflVe~X_xk(ZZ?0SL0C=WXQv&ZtnSpOK%Ns-InySzMBzmReM-?~)NF=}%bn<^t?)Z_{54gerD7JUE! delta 61 zcmcb`e}SJnk(ZZ?0SJDaFW$)golz`bKQ}ccGg03ou_(o*D6=e8KcF(BWU~@eAPeKI Q%_VHAjEuJ?&ti7~0Ao88AOHXW diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-39.pyc index bb71bfc7abe79628130eac79b46a71bc21cc44f4..6710bb1514f8703dd11a762dadc2be20e1714342 100644 GIT binary patch delta 57 zcmdnbe3F?vk(ZZ?0SL0C=WXORU{om6&&bbB)z2=n+a delta 67 zcmX@de1w@hk(ZZ?0SJDaFP_MKn(@}e>z0hSCJQnuD)0kEi$KJ$JpJ6%l*~kZkHn%B Sm!izFRQ-U;jFQPQj70#h92E=z diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-39.pyc index 74da3f04838f92e10370a0b018cf2885cb55e606..a31b36237c12bc55203ae1010f64eb32af0dc5c8 100644 GIT binary patch delta 58 zcmZ1~xn7bxk(ZZ?0SL0C=WXO(#HdiBpOK%Ns-InySzMBzmReM-?~E4{@OqdPhCK&*DOK%@s!?XJwrcW^t9{KN_DcU6xBzgDF(ZX8|fyMdi6S_VJmV^oa2Y z!pH|%DbEYp`5_s9s4b|RWlWq$Od|4#9REI5B$xQ3)WyX$6y89rO3+l;ckT!MgYbS# zhf8TgOTQ2>EM~sb#;?dYa~an7qtm$oHA?N;X0;=dF+1-1fD@sKO07wa)^@vTH6VdX zvedB3b*kSD!G{T{h(z12(Bx*@wp+s3w;PS^J*t-)yEYwbTAOyOV^O`lZ?$N0uUhNa zRF|RqBH6Zg><-N|a8FrtP_8@nO`2A=tcb?QsVbv+O8G`Rpgs8{ch^Siw6dP;_}q;< zqcy6fI*=yl_+Rupu6HQ(gTP}j`;Jsjp5Aqyo%+jAGhO5Q^koAl3md#R{Y?$0DN>%> z?c$hMi=)x2lTt@BjiKie2I4)$%l6n9F3tQx=jbsQ?n2Awv09P(REqEyf$J7 zapHP4`R}t2=2R=E{09tNk2#SGZZC!^cjn$At>Kq*=LxyNe>(T`U>_^odP$kvQu_mS z2SFrgVyoVRO}P@fRVr7^gh;ZZsO!t?5p@FwH>B%nj~`;zE@BUHqQ{QZev{vL_}_eo z4Bp2O+yXQSlfc{ZN02Q+>Tna~J1FadSb~%UDGO3D$Kg%%lo1#X>k@R*2RHVe*aP41 z)6~f727RB-#6EMpBZxzAqA(6v5cX+C3H;ZEGgGQz>{TSywB+y?R!NmFEdDe22;iLA$yMho6S82hqg6L delta 1164 zcmYk5&rcj>7{`70$FSXHX}XjJq1aSx%FtF?2!fGRW|s+2mPHquN<@e0>>$(b?rfhK z3M5AU0*%R=#>9)!gGo=O*_$RFjCU`d9^=7yGil<%gGb-*J2g6o&%EE~=R42)&X;k{{AU?TKF|pemLFsn}IvM>QZx=f=B-JTPFu`FPFZS7A)tCK=BLXB{3<# zH$EwvD$`8SIrX9`X_W@Wb=mHFG&HFUoa<89^(j7~>+qk4zgNgTPK{1MPXHr8KcHhK z<+u46aalggPmImO`Wi5&!1=J_90i?bcocE(YQabq{uj_&EIvu)uBkZlWtx}I&R#iX zqtaMgS>5Jr6rZ$w!dG&7d2NG@`etLps!`KG7>ul`U zwc6%g&Qxl5Z0_5zR_yw=#hL1kRp;#8)wOM#Gb(h4vkiO8-sWNrJyp%q>bhgU!v(EX zMTo?yD?<)wU(x}(|9S2m8|ti9&pZC-MrWv`mfnGql)=t3_gwD*XPSW*lendiV?kay z_nV=oI4=iElLlr<6}edYdJgmByyv!B80_p!GHiV|`Y=iey$Be91te7~y{m&i3Uw3y zJU=CN<=D{U;rEo+%p^DA5+WY}Exid}{xWo2*6jxTWD6h=2~z)h*k-zeaY&>HDxC zk5USzpf}Wu#cdYr^bqC`Va~9ySX5Y4SuC45dL5p30ff_%0{8pmM!pky)Ma*zpc23d!k)Q4j}Vhl|>9i5$0i|1gTpLNXb>%`WO?^#IfaM`y*Jd}Zv9>Ir&b zo5_c!Zp@fxxM0<{)|}0)s?)H^gR=>I0Q4zv)(a0iF?|HXl6?EZ*yw#Mlj&onhm!Qw zlX2ze7cB2pxTb*{z)b~CkdH?_b diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-39.pyc index ad2d469315d3efac8c62116bf9d0b417bf0e397e..5114329d0b6f5b91f32784a7227d5156441f331b 100644 GIT binary patch delta 556 zcmXAl&rcIU6vrKC_h$!4NDx|WN-CII+C_>7Q4^sRx~35$BqV!j)^?<|?Y4P44RX?{BB>PBRZbC9l~ke$?J8&g!388Gq>RT2VQ{ zEMb{oD-;ru8A=fTpxJFhp5!}(6)YMxwvHp?5i8D6<_R|mi-aQnHkX-$npI+X+_avvE&N~w%I>e_mSVd^tK&nY^+j+jJ5e%}KFByk zWC!Cx^8~t5ia>>F+jUk|uW#dp{beDZW19ZR5gsc@pu@tbQd{;1=GLi8`wu@>0Zq8Lb1$J1tH<_t~=e(*_=ye(Y@IuQodIAE`uWWd! zJs}TdyY2_=zJNGX9L4bASe}kV=xO!s7q!N-NCy#;0`anF`CejYf4>3u$v8*YB0Ny= mGRW;)_7l4A5^8uhv#_*BCB5;odUSC33RbC5CAfGwbN(Mxjf_M9 delta 495 zcmXAlyGsK>5XRlSbLYi?;0x45&csOKsi>eKf+oU60|^=sY~(bHIZQ6Fw>}YjD~svG z%ECq)5w!I`un~l7?X?oL5Zt+J@niXR=9~HUcj#+KHWWqb5a;LBevpfvo_(!JYo?*; z2CEgAc}TU&Nu57(Ptr>qxc2{%BwPi~1^a`yM1z-LF`X9utP3%MkOfjcCv0;@jpnvl zV=Bs{hy=`r3SUBZ#AgXZ=TGdZW0SjLid zQV`vP@Fw3y-5g$=5kutQvU4oaHpKnd5~|Ax4CI7SG zk!otZonQj)m3&|ZJ2m)LQsO6vBYgpPUJi1R;h38ie{ajTTrQW`G}gutS;QQiMdAyK rc-0Xr0$b4y%JVJDZZ&AtD3q;+ZJCTJAYC>B zUslG|b~3;dkWxXa-z_+XeV<#)w`OtX_)X(QRd6I8E;}JxLAiRvwLA|2_0_ec;~%gr z70We#6Vjs$Z>f!p+zH0zcF)oz8GHFfsA*Q@K*uctM06=@zIuHXc6 z`Gv)7R*&VFn0F_WXPaVH2yT>`f_0ka*N`zTKZS<0G5I6(F@Ul2X}J-8KRBsErTcHn zr(_}$kCNgJ<+<8?@sJp zp|{tMTiWY;N|Ee6d{z|X8DI&Z1K&qPbsr#F22i`x1b>JRbT8DyBP<^SE5N~*>x3CE z+N@y8=h1qc=Ify|=>7Zd$q*)^7yLW=X6_1Hs8@RL*Rh-c@OXF{z&mlrJcnozcmk{f NSvfEmlivqk{R4Ti#(e+) delta 915 zcmZvaJ8u&~6opwoHt`D#h?s&X5iyU2fJFkqCL}nqkwPFLiVaePgtgus;)S&>&5jd0 zP=p524-ySEJ#s-ofv72Hs79jTAJ8BnC}7U4!C>Ly^PQP<@0ojN->2WDV`d@|-6MbB zK6tNUceIgurcP|f%q*GIE>dTUWY#)0)_tO}fF}5l;P*pmsiwz)lfWt9G>?X#U+$kA z#^w=V6oAkO&`J3x!ds@>B6I}%3MoVr{8RYR*aX6(P{lmLDps@MHC>`Ckj~rso7HJ~ zZ0PhDq{>iTpl>*Z^N{Zqy4R#cgk5K|#wZd8ZD;u7A)dY9mplQ1YOG&UUH_kwRnvMv zFG4!azYM3iHC)T70zqnER}DpF1bYp8tRtKFpM8#pBHJ4oqy>O+389zD#jESQq~d^qQmRkb$Z~ubB;7S`5r|ihqo})G>5A$9JPI4qTF<%>H9VXZhLK zcv2}Aepi#)yRo;+LO1REEsq&Pf9oMy1oFTYpdcYd>TR{Q&^msnb2vj$(cO$c)JA8q z9>ZF3m# rL2Z(MP3|t9fkL&QKH~FO&Hz~;2jHXdr&mOD4Y&o|1~&NX{m*^@xl6rX diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-39.pyc index 9379cd097bfafc1bfb0e4068167850d7a51c85f8..b993db0b5d3fe276b1262268da78c86f14fee98e 100644 GIT binary patch delta 58 zcmZ3b8$d;bBk-M2gp;SL3KQ~oByC}1`BtI>+s94`6Ke;qFHLs*t xzo4=tWAhS@6M2kLn{&%K7#X7`msPX~MDbSS<`fkq>m}!80@X!r=Bo5z1^`2vA?g4C delta 85 zcmaFxgYnuAM(#vjUM>b8_;J2?BX={0Shjv{YD#9JzDHtFic3*uS*m_OWk$*7bsQ)1 o7;kMZFXv!nyfwL@qD9~qZ$)lSQ9-g^a!zJyUdgS^B9%VO08#%SmjD0& diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-39.pyc index 93b8dcc29dcb76457cd434ff21f28f8936c61380..fa5acb4833b6a52b4ba426aec08b2735908c59e4 100644 GIT binary patch delta 1866 zcmZ8iO>7%Q6lT2k+KKHnvFpUKP5m1uo2GGp(llul+8C>81ckIIMWm(f*4{XdW3QQY zXnur*l(r%TM5+f!1;ha)PJo0g(L0=|xFB(1rE*3bC}*Tfyf@n>ZX)fMH*em&Z{~Y% z#_wPH4lZ5R%;lU`dVYLIU;>5 zv3dAKt~kQDZXU*+TdWU$cK*tSpeyKyuU$i(X`JEx1Oo&eaJnPdHHhXkeufRf#rPoH z4F#LAwz94FAbJ$ZbQILWqQ+e~;(Y`e_{v>j2cg5$%`%jo#bMkt(<9<-ycc6kS4nH+ zjqkG%O5`9oN)RVFP8*6JLh~Gch7ZBT><+ul)n;SuGJcYc@k6vh zh_yN3npcgqa(aoAYlgnU3z~t%54|&?7GmN!K_GZf5?f#l$2I&683EaB$S}6UaHr$3 zJV`5FfDiX=`$$^eiJ;i{KC-hy+id6SsK#fVf1?h!y878PeAks`N%*~M!_q|JZ4^x< z8ru<^AtQUqi1V@tsN2&Na1&9ToMHw@& z+WonUOoj0)5bn_<7s&4?kBwg;TjbhL);N6A^M>z9N#@8Sjx4e|NckV(VP_a}!TT@I z;7D=ui}=r!>U!NO%n+?PN#LdlS*_Q#T2XPeoVlAO>Ya zdZS~PDOCpnwfL^aJVZkx=fecY2u29T2~I#f6mdt$6sIUrtFQ@BLm4*Fyc@d8+{-j6 zGUwpGa6hX;A~GRo$y=}Z z=z-{Pj?4tY(|QXblN8O$R$3|n7qXv+%>&zMv7|;$5v#W>Ce1`P-Yy#UU!NUjqgSoV zBXL@3UD%@9P+Mw-z42#sJ|qe%nYOZSI<$O9r$|Ni7!nOOQ!~WjZ?FfZ0Sh8;4Tjw@J!;20Lg^ zu4gmwRg8K@!VSuk6g!-QtzdkWR%B z&!&#zUD`;+SPs5OO|sifGxaHBr{Jyh@wr7@ZaS-aab;OE%=Ub~T&?T8kKTUL}h{<8qMzDz7^p4{T_h?{>ZNm|zCnL0d2fe0qSud5!wUX7u zA5fs6bTroL`0{dcOu-FBIV8q2^xxfMJG4i>*czo okH+~X{H1KAZ&Sp31mZWQ{hUzpB64yMc|Ri9#>?6R-w(d|KXhw}+W-In delta 1859 zcmZuyT}&KR6!z{vEZg$WvMgm;wk%75r6?#+wEUExXwzB>L=!t1cBjj9*`49epj|Lc zYho*Dj3fv3!6#GWn~BXP_Eq08#?%+@gTDA+OzeYCHpawr?v&rS$$Wd}-0z%o&(FQ{ z@#6i(pc)EQK8L@*f3O|~>)egSbV1ANYI;`X*(t8St)(xQR_yZ2?j1K1@Yt94Mv*OG z(!a%$@V$SR^}*})b?{Z7r@9MQc#5E#-~@c$-BinaP@ciZav=m5?}3Y<)^fTc>uT;r zP0B6288x$_@c_Q@B*9sT1?%D4;8IvJT)Y{zq9Ui+%5urpEF@q|7Kh2Ixu(OE08uP` zLqo=cs-e-NI}(0H$r>3&5mmaSWQ?M%>P3z70gCA*c!3~J@FH#A#naFmYGY~K@-5a2 zyP*hk_V!O`Fmlv6AKv$Jj%*wG2r7#BSU!XR^SE4$k5KZkbK+m$D?~pJpPt;VrHb-u zgp`Y)Bza1f^tI|GjQK_NADHMzHAyxHk7_zu0)DC4bdq-S3Sv|LcpJein6(+S`Kk8N zxGam0Um^WGf(R*?bXMnD#x{6K?vAHvmF!aM7s<-#DeHY~L`4L#VF@MA+{KOFNRc+l{(ualgfh4&gi3y_#%{2H8YGNM;W zUq>1jzechwMmaAxEbKZRhPm?7=xG+WNNp0x*|?07@Ga{WcAeiObpg(wYU`UO zu>)bR@v@u=Vl&-wOO4>N`1A1LsqJ=YvPMeD<%f)^q`U*Zt8RjYwoLTd6p(?CCo-#I z-3}VY2I2R%HzN*BxO7AKC+JwuU2>|mH)>|=rq9U-p2Wgz2>k6&rb-mcO~4RRLC3G8 z?Pttsb9|X#gTP4~CE-@HS$+|Q<1MX}EWbrcW*yIX6xQNDj!~#-9H?W?kGkZW$U0I* z@`=ZXnz8`UF>&F4ChO4T%oAM>jT{v@Gzaq{hvW=W;8%YGGoU}wj(8<8fXDp(M2tlEiYml0*`d+<$H zynTY=jFU636HZ2#G3k28OYdpd_{xuz(bz8g*-Z=)pqt41!T7jw>l zZ_}dOgx4;a_-R-t#U$KGrDkQ_-=+8G2?7YhXDr{Kvp`=Z=lUBVX^cRgIjWHeZs_KI Zig)3!)Ru3H828~$cf zvq?6fsbWzP@$#$KJ_urc2&E6QqEH`v(kI1-_QiqflOPC!hzNq<`Tpr;Qw-tTGv|K( z|2s2(&ip%*vDU3?UBiDDwtnu_r$&y_WuBQ@4kd=4R zUv?QOWN@7YJr&01L_j)X`{ebO9&J>9*OJemg?kZyv^=Zj8c(zy*K(s!Z$gb&X?5Bg zncK-pSab5#w!QiLj+DEfN#)EoZnfp(+7|iyhVo1wZ2d?VuLy^RA*H>F6_i}6>M6RP zCCqrPADFfi2=a{ezFqYy!t~2x)^g_fITB1xG8dE$d856%d4k66_OY0jlkv?zWK_w$ zsJma@*}QY;07Mj~Cjsq%V}MSEFe#jZTNHF!4tI>H>BF>A+0Gn21-A(XLtgCYYAz^c z$8VY;m$QevFhZE%Tci4_YxptyVlwJQKG&Jwq1;l;0>`R~aP6$+i)Q!62c73*+Bx~x zmQOSxujF=Z$3@@0HdIJeY)AOQqw~-ol|Se99F3;LGpG@!eXn8%Vljw@+{HR$;{vhD zoV6W`DFe2IEmMmH;RUwq(Bp_bBxmyd$zF(q@>0HkIhqK4`cy!YHori&7nrm4K=@$` zvM6g9=VC@%%@=0HsyT(SAX-2``rc!h^aB!BHHp%gn~;)?Te6&x%kxx3qT9AM{Csd8@R#I}h)KI0S3lDi&!3(#CmYqUq?Bf%6jEt>O};yqk%JtEFAtZ0f0G|uvL z829Q66tJkLX%AfX1JvadAyoly1618NSkhagMk>(00syy|W&61AwWz3$o6k%gw~>i{ zql>r<*XG7)`_Wk2N!FgFIBaL+H$4-@cOj~_dZ=j=pjGb>b+}*)xqu!3h!Q3ovB1}- z7;y>OM*#-`yBWeXUtSlCMhcr3S zcXgM;hLxC_O0}+QQ5UO2X}A2l@6-V})29r2OnHTgd8<-ewVLq25zI65{1^*sV$>~P z=)buM#9V3xD+m2CUTqTc_<*y)Vs)5M%fjRsmER8ZYW?!pfr0jiT3Bp!4_=H-zr+4a z(iZ-qYk>EmNJRat^F2|pOLoCh8><+jxT9Fql(2DY=&<(4=MO^pt=SyvM{HBE4OD50 zl_&J+O<00cx_0lskFLvW`hn##eDOt~F~I-5PA6eF1~?5U0>J-pqj_X%dh(eQXU&t7 zr;blgojFS$j6Oio<1YlnJ0`OoQ zC1s)Ok{=FFXyRm|#-c9(@HlRdA~wzvJi%%r^n} URv7Zlk!{&7JU(1Yem%1PKjvBPmjD0& delta 2068 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%0A>Kp1DFkP z1Hc4;`2Z~d0-y`vW`J7(?f^Ip@Eif19^i3yEaVM)>G`U75iQ36j`slm5a0yBI{@zj z@MfrtMA9>_t7%+R-&7-}LBM@zT!d0Jz!HGv0M`OE5YUxcu?8Pa0P6rY0N@RU@BwrH zgaINwfExjD;upAq6*~y%Ll-tKURHZuji=`N=9;>u+WNXC@hVzR0el4T7Qi0>&H#K2 zfHb8*x=LJz;XsbjNR4r_4S6Nw$jXU?0!v0)GM&JO?r>l eD8c|d`EN#PD*$`$0hHi(CTBFlQ=DcY(x<$ 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 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-39.pyc index 85c7a7b36a8b50f6852a5ed84ad723c061329ff3..98c62eb2232b23466b11fc42fe722a8f21812eff 100644 GIT binary patch delta 116 zcmbQwwUUcFk(ZZ?0SL0C=WXQXXJL$*EX^XV7R6Iil$x4UnwgW5T2x%b2~-fp4H7C( z%*h6cfb>L7j$zT%5&*J_K*X;K{fzwFRQ>Ft%;J*#G@vSdm;B_?+|<01V*P^3l8nhq GS*if*F(M@Z delta 106 zcmZ3TG3{+l06k%#%cvPdt1bGM|1OXqAktoCT(hhBB>YZDK!~|Em zFs|-Gjfs0rG%=I7a_Q2<4XatWF>&L@f5621O$#JMo6K+Sd~?osd(J(xllz{F>9w`d zD*4N`zWEsY(A2r5X6*u1bIf$Oy-t~-OtA_lGrJ!vreE}kk-p2A;wz2hRUiG;v(6WAgWkuQ%R3_ z+V+KLVz#}vIVm&V$;$~#RFUdHm^1`f(tXxG6Kk1}61xIS0#m?MVA}oNJ4DEYIGN~f zM1U9J_HrRVrx&Plh|P#Qi5JJlrLGV*k6VDvAaB79ovA0MeYZIX*MSf)BH@Lpm3AJQ zJc|TzDYV)F+I?+eGeWmQlgb=;1{uE&66f`xE988kviNX z1+8vRFI#IzcHdT>YZxu&b%Tz}^L5xL%-4X}9_q0|`~Jww5kChWUGRGvVArJJMX6)x zML+*-rSSi{tcurzPe%OgAfw1WTG<{0w@5Q|v&i-e^lD1hzWHuf7yL2W9D3Y>?b!x! z;Ln<(Vb~n%k#FPy_90-PyvDI;VT`h2r|H48ym&usp3fnE7PtZ21eSpnzyQz;wh9yg z6Ud9XRGf^7OlnZ_RqDjxeaJXMFJjo1!*%&d`9r3K*L25km=-hB)Xp%ym^BSe{7SWK zYhk*{<@`~``jH#TQ_khX0^BkH1Db(2&;@h=D3U2a0#JcQ0ACkd2hzY@2`^-?ZBT== QF(~`}6Dz5Rcz$;3FTfuE3;+NC delta 988 zcmZvaO-vI(6vsQoR%k_#VkuHcP(YTCmKHF^#DmC}QlJ)s1QX44JG4vbZh1RJ)C0sA z?_^>;dC_?AVq*5-)r0Y5;)RQI@a)CA@#MVSYSg%g-_HK$z4zZYZ@!d|%3<2v9P+8> z`zQNN_;oaDB`d68(BwRY!ZaAWESbGm;?C!2nM7qsFHy)*v&d}ehh1nYkd z{3jo+vDSu@9nFxS7a^V}&T3d4GH7vZ(=ZEKpdN@ys6aVguJLM(!?g1)u}1d)sjXvJ zgUz^%n3h@Zb80c0V@0-Cg*+BV2Q5@@6XTmqbr`b-*jzT^GRM@4RAkF<-Sd1Zd09IRg<=18mn)L!&HQHKs`MY`l|j@pjy} zXye{8VhwQRRmfs8M(w8nR$f3XSikB{hg1ObF>c`9^uOAnNWt*d1SoQ5@ zER*CZ+p15Ww8xxi?qdZzwPk`Qbt7e@5^X1KZn-`&sf9)|qqL(d73U|kLT|BmbkySZ z?G=x=>$a{r3rjy{Omp5VYNQ`oRD78A%4G3b*6H|GT*xKX#g%=mTe6xGr|3Qgo#N8} zly;DtBA;L;S3C&18}I@=!%}1xVK)8`Fg-2Uo!=P~(oQ zXlHCl-l&YQ_;XcNQ_936kijkGkMcn%dtU%=6F>*7BXDy~5f=lXmI$7n&|^I6_b#B! zY$1u32UjQWJ^d(&KBj+bBS8)evVc#Xue!#L$YZM`Y|xory^8G>BpMV+LgT-4bY_UC zXrZv_#|K73(@5DO3T2tDE@uav)78g)6p|N}2RC+eIVEy4c(`D+Kn24sK>YO>IcsS_Gp#bo-8^tDF-3}6p5O_7LTrT%mK0x6 zzuA<@!L=WjsuZZha8A_cMR{BvYc7$g2itnK5m#&n>;UWpn1C991~>#zIbI8D8~`uH zAm9MtDZpv@-DPF0Q?9Iu5bmf+2fD!SlTOXc>-G|9PPSlx;U(=*I_a z!S$r*lutxnuKzq#aCS84`P&V~Hv!KAo&!k0SprS=t-IKCj40{?Y}E>oq}Z^L8a3TQ z%d^b&IOY87*rY156O<+!qGi-{-O+CaM_?czI^@l0n8mzabE?;W!q`4pQM+y58OY1r z{5ZFH%x>G;D-OcM9k1LKo@955PN#9v%c-Q`sq0VaN$wV?60?pQ_L%Zrldsf9*tGm( zZRv95mg)+*;d*Ti0z_cdwWfP4e7mQOWx2Y!rgOQUV4k@@O#*GjO|BQ z) zFy)zDQTD2w-Sq=@Rn3Cy&g1PT+0j44#5Dr9kgB`YrV<{>P;OyR^}SoX%S_qyu>e`W zSC#P2%~K_seUG*LG2QAHdLpT7MQNJx)CjldgX`C6t0s?hl+y${(XpDnBfs4-%Us#J zClyiwR5x8ze%+9Bd)^#^TW+y##SEi|+jtk$M~N5dci|gC>6XwHW87*@B_?2k&-c$9ndpfGRHClQvptP# zeu52mGyD%2_JW)>C~x*OvN>7V`^=92+mf%s$aTOw02gorun16hnN!6uD_P$f|15D; zF|_oBee*eTVMV2UvahOC^;536GmShC{-P@4t-b`C`YX(Z05=I}#@zz_0qCHotZHU0 zxay87^{OI~e^pG`Zqf3OWlWp*>SA0AnGMs;bGyU zO@emk2yA!d;{MHni&%b1t{LbI4}mNO{0pG2^LJ4H1|V&ke0pH@_SIYf4xP`adK*q>QZYNDhTE{<;)_rXm?KB&F%)ZPA$kFw0QK&x(Snu`$eox69HdK^ J%G$x9{{h-S4aEQe delta 2757 zcmZ8jeQaCR73bQH_o)^=#H3xkf)Nm-#lg)~~GZRdBN z>83==@11+jx#ym*d#<0HXOGXbpjK5?c@zD8^#^Mq81UBc_MDzEwD!Fk&-8F(T5nIy zPTEe?d$jUyc{A5@nvpm1*{)ezx1@(p%iwr%VnXMA`HcRc47rPei3v-$zgg*-9?jOI zbGhmoW74^FOO!rhP4#!#u!wJK5GSfo-IyNSD)GhAL5<`~p2_v83lSD_#U7a>4Zi3LCPZ)V}H&ie!!!}H{ zl))*@vLQ&BmK2FKANwur(4CI@78ch*XRy11>sqFJvY0>2Ltw&Wq~r&*q%S?GalQsJ z1@)k2oaff|FqRe{t!rgdqOzgkQDq(`Ib2r0Dq~!orGd8%U;s7}NUzB=d_Smit{0}X zv>x%f!6`GHkdz^e>E*{yljs`#TXzuL!~)Fk5vLm7W)tF}^{woH^Wyq?Ht;BkhWRX^ z@t+Ur%pg&b5Pyt5GJt#m20R340gMC20IH<7ftmrpD}DfQ5b!MEIk925*29xx zLrW`5Qp2wn2U-sL2O!%gUT-9=f7Q<9&-hIZxNS?9~GLALI7aBvQF?;L1l_ythCVr_J@UwJwz645&5#?3h$SL=#nU|a(H9kAr4@0_?Z*2d1MD?AgMWQ*crY$13K8kofVjPq>#_w0@( z(C-4&X0!m^ux9$mn{&E7X=Zv1tDxEGN&Y=B#Z%o8_Lg{~`xk6U-OMY_4|--Z z_jl~FIJ>vDTP5`ixQ`slRTOPnx8nKil-@;y`mk^ z47$sDL$$?Q5L^L#2Dl3N9N-~yT*Y$D?Se%SOg2&NG05Y|E$q6;CwJ7U+u-Fl284U` zrwGHjkj%1?uV4%hEH8(H9$o>%0nhG{Hh1h1FE4)zdB^ak)mnq{Te?k z#qrcS_O&>j8o4zFwK$*)pu+kZKCkB2i81D-UjsfO0xaO;*PWhwgBSv-!Jg8b85Q$` zVKyoj2OHUbab{2i#|04E5fPsfx0 z7}h_+dbMVy4dYOum`~e9HBAn2oj(bY-yDB{-Wc8ld*Ng~tC2 DC{+2W diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-39.pyc index 2a04a89005814676965c55336f43bb53f6cce039..3c22dd383497d0d73f285dacbf3d8caa7f87b16a 100644 GIT binary patch delta 9650 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 delta 760 zcmZ9KJ8u&~5XZf~hu3F2e!vkFq=<_jkrRTIfCwN33L+7a7ZP2BP?!nH2Bos6B~->%*#J8kCe%6;YbvkOr4!v6g&ML19(nSI|>Jj3N4+9b8U`-${2A zrAMSE9T14R71*lZ>`Q3{g!?+e+$B`m=0Cu!Q!_8Rl@J!6z6wglGJT7 zUf*Nwfj-XHoyOJ1=prCV3v5+(1kTEj#-}T3amgS3|Gc_W1((?;%uf zx|db&ba&gn)Pm5Hdbss0I*Q9ggSnlMAIKDVA@u=sn|^N#j(D5x*h^UD5kmd-L$n-` z%Y85Po8Z+!EyKlRsW-aM-Ln#ZbNA;~F=y?(#Ih;@kcq$#!qzMQBP=2l5F>hg#N_K@ hGyjxqh~xYryxxUE5#AjuT(H+cF>pM+YY^`WE2l1Bn%V#W diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-39.pyc index 714853b942cc054822a0cd17893323ca26b7080a..020d8e8282a5cbc9857a32e9fdc7ab960632b616 100644 GIT binary patch delta 2930 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 N$VP3?Ln=l2{{=Yl+}HpB delta 20941 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 BV{QNd diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-39.pyc index 2527c1b8b8c95257ead7132c7c41045c4ec43af7..14d2230457403b374d838896fa6817ac9cb68751 100644 GIT binary patch delta 1052 zcmZva&rcIU6vr9c0xiFU0}ur)BG4M8Mk;9$f&%4-iU@L$HL|YT0XE(4*0)n=(P%L7 zM-=oh2jWE|H)5hOO+0(SvlkPy7ySdgdhuYKH`Umvo9rjw`OdtVH}B2+xes$yT1`!$ zOnj;R&)!red_>_hzTVE`!uh@yS+>(Ok^;kF_96u*GHUDDG_{x$$>iBGf9`utqJ`=5 zNskD7>TjvSFp%iw@BD3Kh=2BPlUU(SV7Qu$@ZH838Rb73`#Y4ntVMGfsxz8YHCS?7 zuf`Y@V}EUMxoLCogxGM$3(dH%4>2I%mQzc&lXPbfD01j9Fs!B0U|g#5&gRv9^C%Y( zR}m!{7Tz{*`^afN-*$tT{A1e#a*8h;cqy(D2uAAgAh?8>5>WU=ur;9L@SGgl!C>Ec zR1J%U$wX~>R+kM%os6ban8u0v-xH2z8O&It00|ko8$2>_O(;+i^@wW383ETPHc2}$ zh6eTpI;G398I!^=8ngUp`_%18lp}~ygdZ`Em_XDZ&LV0B!VSeb1sG7es+lQ~3SLjC zG%Qt5YD@#Xnd@VAidv9FU6HhPme0`Q8H;EU)%9bOR7*?uQzanvie_f1OHwXbQ3BVq zHlwO+WEvwpDVi^>xbR@8(0lNUr)x;)ut(+v>*&jRmvjfcIFEO&pOj7Lz%lmHt-VOW z&`eR#1b_|U;v)b&@b9zo{99K)dBl%(ANI@IVZr!(_h4)WS6@NMCdhVRN)Sin5r1+i zzDM+8{8M+F#CSs}N;dd-sC{e`?Z=2G0&az>io&Vtf1@|ViY-!B=6HpuBwhmOhzs=b zSE0MD%HCYs>~XXl{#j<2PVsSs#3F@X2zT_{6bf!34k2c7qEa;+HLE*Oc!=H_;vV8Y he-UnqMp4R}wV;X#xc)>=rx|A0mQ3KET>00q@)MSc0RaF2 delta 1074 zcmZva&rcIU6vr9bLR&xrF+hM|0WGaD_CNvKfC)c}prR0a5lq%$JJ7Z5?)r90sUCPXuSC!7-ORIwjrW%51)MJJM-SWeQ!RcKct&zOG~g$ zec!9j+oqI{NU`J_?ip6j4?9+18H2{=C}d{9*kG~6a+Zq&-y1Sgx!y4EiO5!mfkE@e z9R`|Zb4NCmXgne4x zpri;Laiqe^`>uT-nHGBAU1EvPeGkc$$ewtu+HpJ-8^w!Y8F5uX_N*Cs&cHcqn735b zT7hw@=~)U6jwwXj zYyAsyV5~O8T7Uh9sp%QYsrzTr$E_SQVO@pD#*C%&vdwCD7-$hq25@+qNef9PgRb77 z`681fC&`8k-Y#04Y3_h+jPT@G`RF8+2a}bFfiIr$q|#B3TNgY+-<`vesiBt?)8Ttf z?r;Wiy&|gNj&6JlfcgJTy)Ax)lVn#UhfWJ~XnYFiLCw56)o#R!)PrL-siPpoI zco*4G&+mM+M{zkixV57;-~r+!BCR0(n&D_g-HF3<^zI{`BAy}o5d#Xc(QxusNxiNS fwA{byMU}wKKx$KGHa9HOz5IW5O8>a{8BPBNy6Y6> diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-39.pyc index 1f8d1e32e01ce4f58b0b32634e8ef576ddaea58e..af760b3727ebf091d254e91b8705fa50e368179c 100644 GIT binary patch delta 55 zcmaFK^qGk}k(ZZ?0SL0C=S}3kq)?}yk)NBYpIww$T#}!bT2!p>lAm0fo0?ZrtY1)B Jk}>gf835vJ6T<)i delta 45 zcmey&^pc4?k(ZZ?0SJDaFP_MKNvuRaH#H?QQQsr6D8;2Hvn*9VpfaOm;@>g=P@@o1 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-39.pyc index 64cc11a24d893ed50ffcb9007675510d32b9a101..d2e740739607a409f97f6239810d48ffc23722bd 100644 GIT binary patch delta 70 zcmX@gbDoDgk(ZZ?0SL0C=WXPE$EZ-PpOK%Ns-InySzMBzmReM-?~oKQ}ccGg03ou_(o*D6=e8KcF(BWV0mG4JO80 PlRvRcWt5-X!Fn73Q&trG diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-39.pyc index 633aafd8b34a4c1992098237a9d16cc9cc223e70..5fee6befe6681b229bfe83ff4b346e16a8e95455 100644 GIT binary patch delta 82 zcmca5_(YI9k(ZZ?0SL0C=WXO>WKyWm&&bbB)z2=z{-C_l^H5rSzCo^%o zT1K%01@%($bBj2EI-_{fQ%hX(bA9tuN^??gafbl4IhAJSq@)%Vfs8KV1`%u^m6IE| zl^CNYFXq-Ugv+dCC=vn6{c6?E$j?pH&o0U=F3C?zEh^S`$xklLP0cGQ)-R|m$(a0& cdkLf1t{QoJAo#Xtl|ClVn#`8|&u01|pTcmMzZ delta 204 zcmbO()horF$ji&c00ckI7jNXg!6ko-C8r`cN0aduS87R7YHB=)cZ(Iw)?_T=nasrP zYI%ztD5#f`pIgKU)Om|1J+;IoKi4-ur8Fn?7Iz3xn^S3KPD*M~5jRl2hzCTlfmBXz z;8tS1HF+_&jyhasB}0)UQ0`Z?er{??W}?1FVo{1qQD#}Hen4eL$t0d7jM9^r@>ogn SflQGG5g_GAgw*7pJaPabEjh#h diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-39.pyc index 3d3815569019754459c0f165b9c2487006c78cd9..ea8132940073df943a29a409e4fed516532acea1 100644 GIT binary patch delta 1407 zcmZ9MOKclO7{@!^*l`|q6I{n>oU|!PY&OPmQxcj~t>P*V6{)o%gi5qRz}k$P)Q>ga zZu$}e!lPW^^wCpM#SPJ0yXuijJs~bgJyfdpQdQ!L1mb|oiTTf_NmNVz?YA@Ed%oFU z)_z^3_rEtD3Ss#d zA_okS^J}qNVlt=fO@oHigC-TMPLj2<^O2+smNbST6*%90KMHj+c`KgupLef|-n@F> zHn;p{Z$g9`6H4RG3voI@<~Z!K04!(r)%3&3d@CFhiQUH#n-g_wxNY0kgZ|G*G)Y^5q&)YMTZv{Qh*wG4o_yh6$JM2s>FcjUs5E=~k}AB4?YA*cC{U1>CMl9@vCZwv4V->kX00%%O)CQ2ib`6kpt3K9|H~H$Te~!SutQ^#K z^mIdFc-`bL#>TRGj`aw`*xXx830f(jpj~?WbnLeiI;ChB^c*&KJ?iUlMXi|~VNcNH zy&k6gf5sO@S|30HdpqN&EY9-zY-YylQl0g5d#v7?<9d=-ZNjV}$-t0}=F3<53jdJ3 zE9SYJGY9mu+gDzH6u2ebo8cJKhm%t6+8+9Flv7ElGpF`tqg&^uwF3GA#Nv!k( P_`1-NvQG1V`NjVM_?tSj delta 1424 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 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-39.pyc index 64fce2ba9abb06f47d4fb010249441b616bd38f8..fc79383a0fb424c6fc9155290918df6b5d4c9a57 100644 GIT binary patch delta 293 zcmZ23zfqn$k(ZZ?0SL0C=WXPE#l{#l`5RllssvEvSBri|er~FMc2Q<=Nq$;tQL(;D zesXDUYF3B;v#hrgEg_Fq^P(^6~yMu$xlwq l$xF;ly~SFVm{XbxaS7BpQ}`}RDS-^&1Q7^_LZut|)c^~9M$`ZR delta 400 zcmYLEJx>Bb6!er^J-!Tf0*XPvT%r5|W1%L*%F4oS!#!l>*t@)4P-*P7yw0etHQ|R? z*u9@%uQ68c9wcrtc{{T^Z)RG1tL1p1kXFuvLmE<|!DOu}@*Hle)SZ}I2wvw;>Q_&`vFmt!mR`OEl z-8ZZYGeB9%hoEBK1x0HyLQmX+!kU$sicmv9uFx=4l)d2L2u=|r#2usiIbt_F8~_rF zMmip8VnPNWHSQWYjZ4c?p>NGxt~Dy$v$IzXqb?8aW^%{Yb>3)E>$Uh%P6K+@=D+Yl Ieq3+;0i4Wp8vp7%g5PKO?kPP}=R5|KT8JM(_#&F_!J zUy3m`9`9)5-){QzCow&cbqW=`Y7}+xSqjK*AHC(scV)M#eS;W z;rhqjFS3ix@49!GyiDfV29VP}TLg;NjAwa(5g6n$q;R2UbXJM)*k+ACR`T{8!}WvP zh6m^PeqItG_(8{Z{fOq2xMy|457@gtGZlQ;18k$2=$#Glf~_Ue1!0peLWXX)i`#IO z%YM{oXof?Xf^|ATk>lf@A^axs2D|ok-(40}q^p~+t*tI9c)!2FEk={~4~4M^UARan z5*7#-2;x17qyUG~quILQ@KC&xW~r`gxUfN+y#y)@oFTkI=qFqw^bqDb@}XmYg@3S) z0|VDt8GlP<5C^{O8s?{bsV)i#W4Mx%r83=?(Mk2Ui)!O1sVmInH=Z#Kza6|FQ4L@T z{~jF84bdZ=@D{C<2yYX}C>Vq?&Zm?4Z4!^;R!OZ8x{lCIl8%SzDW*4@=`Yw}fv-Go zV^n74^7A0=zs}*aO;{8EDR@=GF2=W37M5GPYWc;CHOn zbfd8ZU_&cm|4(NaPLrioe3}`ZA)~%z*FC51wTd6oDk|@ODo;t&M~T!ucX|fwJzsJ? z)vLP-&J5jS2l)NaUm1-XSoYaCP*neRE>#_GKdakS)vUoX{ycoX??ehkjt(%9mD8qp zTy-2iK7NS$8pin&AI2Q6XHQS>aRnNLm&Hji+`8rYlBlWMYJd}o9>xdRc{Yqsv(FBN zYw#Z3C+FY>fl9mqhn)G?$?CRTqf@sC9}q-8>m=PK+~ME@nIri_!d-%JlzfDHgpUY$ z8mp6iKrg({+S=Tg@L@KM6}gY8ctcLdgo88~;Nl~>khnx5b(bI3?5bm02He6w<+Gb9 w+7PB?lEjdVkwlpjqtTkVBB^2y#aM~y5&cg|2NBQ#Nur}w%!QKp?#Pw@0EQ86!T7%g5Pb9=>y8TS>yTOt& zfV;~+{&+CKhmGEILRmYWb_n&Bbo_H zHUA+p!GDVODaSqIAJLhrh@CSk2Iytis9Tx|kCEvKgb09cgW3*{NS3RV_h?iN=dgWhIL->+Z~r#US9TS>>Z}^uVSZI0oT8w z{A=e)R+P4pE*sZ3y0UDs^yGfB*IgJxyQ*Lk7s)2!9g(L8yK&D!D?6 z{DboPa0X@3t~blNO?85^v?0Oo^qQ>NitM|>+J&;P{K8yeO7L5KO+2n=|FugpOqjMV z5{iTZ;c0@*9}jHLLQ+8b~BY7 zfwMf5SYbAQEAf428g~e#A)5wS{&Ih2*e1^r(s!0LX(-vCSB>W9`2I-ExBE}CCb}oN zZ{TZok$*cdsZc{;?t{Ux`5~0l4!A%HlTah12@Zkci=bKG(DBJQt_H5NVYsW%AmeUj zELyJfoj?x*{{G-NgVr~LpRyN^p#D)C!x-$<;v+xpdI=%eGQ1*x$6-eP7GRBxrx9ul z-Xz&8FaIRjpQVFDq+nI_<}^SZyn^j1XAe0o@Q2B<3Gx?8z2Vvo*Xw$qysF_1s5>Ru z9uaQ1&hZJTZwLkNYC}L3bLaD-_vF z2j4x_G|lg(pF=)OKe!}QgRA60$-y-OHFOECBh~2MW_qd7u5H2%f_%Nsy^gR&a}Oo8aYR@nYtwgA`b0dHVX6@@gQDAJtD7^-`mWfVcU*Os;o{M0zwL zRIb--!_;A$?_>@v(_gI|Qu&I#>By3fY9?pG8@3`X7YTBnq;iA2$`(m!g2ihi G)&BrqsD!Kl diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-39.pyc index 4cd8475836410ce45c47f5c3d831bf0b8deb9d1a..a905aa39ce9330fa4b787f7c3508b3dc303249ae 100644 GIT binary patch delta 60 zcmZo(%hmx}=ivZd#3mx}=iew;7f$UVznEK5H(H6=4q-y^Xo#ib~-ELA_CGNWYkQU4Qc E0GXo^oB#j- diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-39.pyc index 7b3b39ec5ff374a40eab4085dd7b788cecbb4409..921bb67af36c74b23b0ee4dd521a669a007e60d4 100644 GIT binary patch delta 344 zcmY+Au};G<5Qb|UC(w|z9ohxd0l`o)Wb4X;gv29wu|ncBQPVg&J3>rd*cc;L_OcceX#m&(M#9px-lRdGhk+KjS+}%0eneeJMckl-W+Z5LXK> zX}^rk>>dimH7aP3GyuF(tQ&875E{{M6XjyXqa~Q6$T-O8S|rWNa5AbNRNnsJCp2sy zo%z)Avja_}ia}}2tF%+>%AoynZZAd#DX}Tr^>&SSD`rR|*duSq6pi0ALeSONuyAO_ z9(4+Pxnt8%S2cCXnZ~t{+9`RaG=XA~D~;Hm>eZc(PHp^1dyJ(bVGJhiw>vo>TC@Eu R=yq7>U(&t>2JNMH_6Ls=T`vFt delta 327 zcmcc4cb1Pkk(ZZ?0SJDaFW$&Kl{w-TYfffyN&GGD;{2kL)RcG-?-pB8VqSV`@hz^L zM4()GQD#Z%Eym1Syve0SMX7lu@nGqd3`IgfgMMY}=ccA)ChB`67NxipWtOGt2UKR1 zOlD%~W)zv+$6_W2Ql-gsi?z5Uv8d!0b821+SR;fGp8SZ#OH~x8B!?MD{ICCC&kQkG zlkpZ~5sJz{Ryjt=%>}HijN+0&wM85tgV}GfWP+T;2jtwE+`}fz4YChr_!c%ZZzYg2 z&Rgv9@hSPq@$p4cAeC$-l?9o3=|xN+#UPuDL_h>6Y>L2!gLEO;4mMPHvMIX~0Q)dh A<^TWy diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-39.pyc index 7510da86551bc316b83ca0f5369f199a473aca4d..59011b3b357c0d391ab8117c050605ef3c4dc4da 100644 GIT binary patch delta 55 zcmcb^_>7S|k(ZZ?0SL0C=S}4HSE$g>$j?pH&o0U=F3C?zEh^S`$xklLP0cGQ)-R|m J$(UG>0|3Xh5|ID^ delta 45 zcmaFHc!!ZYk(ZZ?0SJDaFP_NlFP5jDo0^iDsPBtd$j?pH&o0U=F3C?z zEh^S`$xklLP0cGQ)-R|m$=DpsB+94+QVLdIBnV{PVg;FzBnxB~GXV((wj!a)UCb}J lk(5oYW07POojil3n@tF)qDXYICaatPLIId1I60iv0st1YCSd>o delta 202 zcmbQq-OtUP$ji&c00ckI7jNWNVp6-sR*;ySom#Y#p-2!Y{3};KH#H?QQQsr6D8;2H zvn*9VpfaOmb1ai6qY_8~SXGe_kadd{q%%nt$Sh_85)5ob!jq>kzf?t2##WjKQm6(} z#{yEv&cRqDHhB?Cw}~*2S0n}`Zn5O#C#KwD1(C(KSW-%J3vRK3$YO|nNJdUhWVHYQ DS{*UQ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-39.pyc index ffd180395ee2bc16f3b96b412eef499e38a57552..c9b7307593bb390a9b593825e99a3fb5d1c3e366 100644 GIT binary patch delta 55 zcmaFN_?D47k(ZZ?0SL0C=S}1eS18xd$j?pH&o0U=F3C?zEh^S`$xklLP0cGQ)-R|m J$(UG?4FJo%60HCL delta 45 zcmaFM_?VG9k(ZZ?0SJDaFP_L9E|#mGo0^iDsPBKa>wV diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-39.pyc index 81fa53b090075538c03d9e1a179f6d983a93c7d8..7f80c17fd9470c2684cd049a2dbcf3f03bfd8d64 100644 GIT binary patch delta 108 zcmX@gcb<A7AKQ}ccGg03ou_(o*D6=e8KcF(BWV0~SY8J*@ zllQZU>EGfFNKDRltw>HSD9OyvyTu3Mh9%~drn(jtK{+NM)hW!x$Y?z|S4d*>5)n~GMjH@w@+Hyxj8>C3iEWg!0vcUp m10w7|gguCG0TJ$#YsFI;9VR~(H)M30EGnVQ=sej{A_4%=xhbRo delta 138 zcmbPjIMI+hk(ZZ?0SJDaFW$&q#w3=ZpPQPJnW*oPSd`*Ylv$RlA5fW5vUwrXB|gSm zn@a@cn1Iw|VJ1dKo5>5fB{r`U5oKhw1u-Yz5xvi7J$aAVMk#Bcfkn0;!U04$f(SPd c;W@coJeARD@>_93MwiL*63UFOlbt0Z0EfdT_y7O^ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-39.pyc index ee84a18e8965a38e8a6f8568924b0d9a00c14692..b5ced6232bdbd84c146d8482942138bc8bd6bf98 100644 GIT binary patch delta 2878 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 I>&P?z0#Hk>?EnA( diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-39.pyc index 45d2b4106fb4c38b17e2db2ad3f972e9f93de613..f3b949d796816fb68e52926348a2df7654f10c0f 100644 GIT binary patch delta 640 zcmXw#&x_Mg5XXJZHp!+`wzi5;i?#M(w%aYmUwhcgmTqlPq}9d4VM z4<5ve2QN>&2=1RC(!WFy7IN~s|ABaN=BWeu%$v;2oA12$^^f)3IG?vJq0P%*zU6*q zs;^tKaN)J);Kw4IdJwm|p_?qcrHEV6O3c%aA7}OR_`278usz7a!RqCfgLJq%FkAhVBw?#Jq#J&-=HHiohQX;}Rh8MdQ^Rp4 zq3bx%!$i6{O_r_*!ytwV#!w~f6LN&dgy+&Mv|F?-6bRb{^#ZhDx*0&?xMO$bDa~+1 i>0LQ1+$i&nC>V>>!nHxfuY55}vk~}90Udc(nEwH8shmat delta 629 zcmXv~O>5L(5bnEiH)&$Z#?_(~6>2N4RhJ&LwSs7A*96LL7cZU~V?MT_*-e}z(tudd zn+H9-{s1o?dJ@?mqBr3cM34IqN>9#Y+krgqd^|JrOg=AsSkN3@SEta9ex%>Ezm?fn zt%2`_PRn$_+ko)3-`XyAvymnpRStx-e1E+&K7;g>;9zsBEhN*l#tfsTBxDQCG)z#{E@BjKk~Q6Do%NdU#VPW3WL?r7o}jeo0x zhOkCJGH{l5h&H!;S6OiCwEUKC;D!y6>Bw8d6Bs7_e zszL0U$(O{<1?#{fx7c$Ni?V?h6je{2FDtrPU*aI63`nX-2}D!^iCfHxd6k-+MfD(o z>d8D(^6F8XIT^+AWr;bZsZpFoFlLcFNClWs0I^yo2TAEOwoGo4I?32R*+<%ov2XHp z>9Y!bK*?Lo#g)ak_%d?~a#BIwN-W9D&nxNyX{(vsA``?B#gbW;T2y2?`Je)a7=rL6g8|1sF$?=LEjPoZSV3(Mrq{Tf6Bt98L zOqgt{G>dfskQp`kijoB|@OYKwtfRQYT!Vr={r%#deFLI6eI0|mU4!EN1EP4K%rHlv zP}e9nCx3q*pePqyG$?9vnzAu}6gO1FF~r}uXy)V<$~IDfRL5|g=AsX0a{>tGTCS0SpCkWjX6x++nUk!Jhtp@y@;hw>W(rgS=gX;{5||@j#hj zjy|ETx7eKg{e6Ifgc5XE(DC2^9L!hwRI6^OQ|6t_~4xJ4Uh8%+I$?EoDKSy6G@&^8IXu22uC zcP>cmsS@G`zzOj?5Jx1R_$ka9rQw1lKhJwJ`#dxIVex#?=-2DjOZXh#`25XSEiJt> z4@SqSdB_Gl8||fxo1M|_$#FW&xH&$}4uoC$Qitm6(O?*5Y%tu1k6K5$E2y@qtckZ; z`_>A&v4sn`E~7OBO9uDFFRj~x*<{29`-5TsDB)S3Wl*0A>F^c%pGUXw`2JG2)OFDN z+`%r{6)CPucz|$E%S${x+G86?a+RfTawP@vqmn6`qFw!|EQ@(#`L?XjRXok^T%1%{ zORCx!JK`X~_^PyoUW;4BZ`-oYmheQvbiyJk#xybU9A92WC@ZDf+(P3jGsSsrY2^`0 zxt^Vlac67>2~!cE68qz9Fv3l+lH}rd?b8{Qi4!~~UeC?T{A4_4Dd$jj+99#FX$<9X z66sDrLh6AY7T;X6eAgvViKuH^zTcNNoEaH0%!bVtdP`VM4tQRHr;I zdBmll-J~z#kbv3??Hs`YqY$FRv7;EowZ`fhG@j8gLcb)SL9@9rIMgg^;!P6}0GoF%Nxrk|Tk)3l%xQ(qw6elFHAA*j`7D_Nbu_0b3`CA4J fY&ZFbUzQVfl8`>_*&%gta@Lf)e<;Be+U)y3^+U`B delta 760 zcmZ`$O^ee|6g6!V+NMp5Bg%+6FoL#=PDiGKf*@~_XB#G8CaF5BP;IP{+Sd0n!mI|j zZd|;T;4jdX_(NtX+?`u@?p%6bhfduX$jLqDo_Dyp@6*=DEqzq4S1;i6=ahfbTcyjq z`z9S{qwZkD#um%orQP88RW72^mpW8m&$C&Svurj2QB^JFw(!+EN=Lj`_iwZ@gl(R~ zRatcqOj+!RpKAXhG?F>XCfRH>O?WueIvcb9W%QRB-zS<`?0`1nPR4V#A;qqQ zU4*s@C7w=SvK|sBvh*z|DTp7HT)8Wp>Z#Ha*YsQ4(ho&E&2FBbEHX=~>H;U?AjbMv z#S+b0+;pX7AR&{vyxjxDr;9T>PqiK7lfEf&uY{E|mGvV!=|*q3rC3#5|xe zl*3h}IROc&2U>XcRZZV@2~;BL+NSUL9u!CndNB0Nct~O!1;e(e7u%0)8Ya}Upt|Nz z@`y`8y-uISA%WsBv?Vy8FNG*^>?j7YZM06nctXPn^OArDz25GcJG4*CL(o@!-=k1l z5tn#}cIsfN5&pr2? z=Q;P%F#BPc#j6g7-6DQ#GW$=)&$H!hENKsiw30PEpc~;fjq4@z!v1w3t;5huB3(v% zRI`;QGf%WX^-sp0r-!Gc)A1=+lovz_KAkSRQz$1bCOVLo#8?ZROiw9Y2~RapBTy8} zAAwyA6bg8fI>J1p1_K+kR&T)2Li{o5=(D?NPj0vJI%f1xgOWnG^X*iY_tJRj zOx~99!}|Q5@x$Bs#`xi;smB{aNS6f2kq2B?$?4rua{@Q zA+Z&f6A07BX-~2+otUONNC-tS_ZFXBupq+^#mbuzISJ?y7-D=sZ7R@mJD`*Svjs%l ze%NmT@+k+%T3E{ZqO%I;Fhxm^4;Vfk$W_kJ^`$a>mN4_5}1A*^6j*g*r8 z?aJ_&u#@uVma}eZncJ1qDr7Ukr|O!wQ*=`x+%a_TBr)N*sKqooR2fUju2Y34ge2Y? zCu$}JbZ;cA8(a%&VmAL2;hz8}A*94ALwOryR$d%fp;(P2G9$<3Ali{Kp*hm%HtnF``=a=t=`WN zw+1K#Du9e}plj|pMs(91VjgO$(%3=zvT7#N=#Q%6>_HK@%4)IbiNdh37?#NFf|INX zj1N*-^})Cgg)W-oEd5xm6`d1<(d5#S&30I5ZAhUA!@?4n^>2PS+E#OsDHjp`Eq2^@ zNtkOz6d!@c0Ed9dW)#J74a4_=0pJ7Rn1HDSI>hN2rY)qdH)H+nYM?_L@dfz55%Ac9 zS{v$DRI!JS&dmIqnRe3WVvM+I;(WFtNLy=!M#~j9sCbi&ANE-3%(7pKAYFI0odaQD0q2 z;vq3K6&;<^%1wF6->UO4X+_n=6>QRFq+0=81xz}&B$r*2x9RmIr{c%lCgrAN(HBd% zvY&;OPEE^N6zq#kn?@tcR?D<$G;jIY`%Aeox|FQ?a>YdKdAS7fVWH0Y)eqFC<0ke> z{4EwM_wH+$sjS8nRW^x_7B^f?_*DqYxRk%A8I4Z)x)a1D#7C&PagkH@s7(z9xqRB= zm@mukX7o(sWahy9BKv4m2;1?hk zs03~R50rcenvZ%ji`iwWSusBg+gS7%FNOX#AZttZ;bt0K;SY@Uo18ltF}U-25cml| u4VV+Es%w^NhRQP`$pwUA^#QU}WM7}ga1cO8$Xes_C^N*#rc(E_3;zLa^Blnd delta 1857 zcmZ{lZERCj7{~XlaGCA8jSX1$Qek5oRKX#lY-5EDLCb_OaU(hy6x}IGjAPiyn3_WCsdhT=FpAk!KZ4-XoXLcCgMl)>q z#dBPlp1~Pew`}MV4*^CrIeQ^dJul5Epa$NQ&Hh1T_;-#o*#5GI8xB- zYQr+AfZF7CSUZ57z%F1nu!kE8owm&|vw)@CxuMzovT48>z|UV-t->$QRzsyh zo&0&_!_>@wR!(wu%aSFD2??PTX(Z4vN+GLcT4FMZZk{>&&7@;8F6H_KU!QHbE=ngZ zOl4)mJu0yhOK8$apkzwCD~?73k6$GEmN!*7He8nBpezvm(hvmLC1Nzil_Z+sz5^Tq z-UWIkVw%}1@0D=O;@8*2hBvk7W~dwVr9&XR(SUWXMNI-3c6EF$xHBmuI~72bdF36YcW^iLP^H z)f~DCU0A=A;kVTr@!_iCl*6dfLeR8V4DhuoK?CyAbVOG@RZ3}BuuvWFGcdp(&CjD7 zQd1dxWB!M>!Sn#9j&kss1rfR_tz6ctpVcr5+0r>Cll!Zet7S8}dg19I8~G`|k)oOs zZ2;Am@MvCF<5fbNNXzAgI%R~=kz1i;-NbcIf0uk)2CC!Xt6a7yTfNl?i>&JBWsBxz z8!|6P}2$-vHlS~zbKvT=yzGwi15P?4>>s7P@zwngBxvn5gb-2`rSLg2>VmJ{>)8YiIE8Lrt$-5TM`v>rB0L}ma diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-39.pyc index c5585aed04aa14ecaf11f74c2c5885edd3eb7af8..f20ca94e9fa47ed27ea8958ac8c2397560ece83a 100644 GIT binary patch delta 3371 zcmZu!Uu+y_5%=DIpYJYl>cn<@uI&qUvupba#%dEHje{(81A*u0RQ~A zI=1Rm%&~Q{Jl|O{$s3z?iq(o~``#E15YHxFQS#ysiIXRKSzc8LC*4!1pMRu@5DHj! zi=O24KwVBcGxz|h<6=AcL_-SR(u1UW#9xy`d~z&xeL-4G25HN)Y|l6BqDdXB7v$z0 zf41V5P55gr%Xnq{VJ6_I8VNleI^c--MQSl$_Y`Tm&j&HwTI$=M)%#_B-s+y}XKgKs z6zkTq8VM3B4pj_4h*-<_E6k-=v=gilq+D`bllVelu3nb)UtgV zW{OS$#sIjyJs{KHAu?@`WRV$mBkCI^%I`eYHl>_>lv#l?s>Xw;XZk_hbIX<=M2+R; zFpsS(3dHW|H%v;oo1!;YBY%1M#T(b z8wS~w7ccksic8sd@-w_k=V3Q~!zfqHed?{b;lp#hhtzpKSvI@P_0}O4bA!W=LrKvI z5vWR#B$It8np}p@GH0KipX3T%7ehO_ur>4>T+fyRPyUws{ozXoHGX;M;qK?55e?FA z?Nezu%9;Dup`_Bjz;w`}r7qU=>6xjk7c`M-?@M21?rw@f6Q6DGkV^tj6VJ6TjywaM zlv}G9<+4)@V%4HIp{D67*ty0jy6r4GKFx_gwvTU(@RpjPMgEa#qI00W41h7x0oNI{ z^oHfH>dWR*wWMXZ$8|DSicZz`wIo*NrmtnCNaJ`dQ?;$4vux^~b#q_h*<6s-F;~Q` zBl9Opyymt>@M@f7uA~=J%m|&z?|gFP^{BESwvR0iTFjnjc~slINDvu4O;3YV!g`kF zSrGp_=BaCtq;*Cr18hLJ56WTq3kX;Iu(Nke1`XqCmWuonWa^iwTQ-*-GDQa93ZNwZ z-Z}aLd>~w85GTVfnOwvV@L$WAn_Txr%h!!1E1ZOIImlKl+o8tAgsw>^3u3+NQsO48 ze@6VK>#0Yz_`-ANre@VBT>$e-09kTMXii2|4}GM2ApaE>;AF}UItSss$z1DxQOT@= zdyQe9*2Krh#|@~E57+>h0K~^JJ-|%R#-qU`S4Z1vx%#3}_Hx)G#C?6T((_n$8x|vB z!R2>;+Ow`CQ0YXXySI1ZCG5t+3^x*$(P>Bc=J0S_I^XT zDi1(0@Zhm)YC>KwdCb@oFD!)d)@!h7Mpnjs(cJDk({&5S^6W9FxEiD^Pai+CWcl3n zf9lhYeiIhI1=xE#Pxlu(zb(~dn+2(&Th*a2r`Erf7sX2hJzKAb65oaPTMR*Tg$H}w zb&Hb|oW48E+KprLO~7jm4Q>JqsL=Nqo{WHcgF%ZMRGFLz(%hA}CZl}jNofH`kpRfk zAWO+2w2VFcVJ znHQ}XE`1)$F9MKuLNO8Cl^xB~QAP)!wKmpX#MsvPHK2LOAZn^%GgovfuHiSDRm<)3 z&ZBo&h#T5iJJ`_j@(W^j$j#nm8BT<(iM&{O2PIDo}JXP zA#I>Gc&jeRmw4lI<z`FQZ; zYfB|iGBo*WZDaW=06~U*E?fLAmdyf_51UL2E+D+e4?s0jAt}^Mkb0uxELVj)_V)h) DvJ3~k delta 3399 zcmZu!Yit}>7541YUhghW(%4QM6Wbdno;>VeyG{@^)NazoZM<=lIIdH}c)UBdC)u4H zof#)tr@^J9h?qVgw@}1OEiI2o{77Pi1eFS?6%qsS|fWIjGL5M$9|G@d~?ABf< zEBTu<=bm%!dEIlzZ_KRBG@7YYqKl z?3QK1rjk?PtiB%}4rO<+KD7fr%^)KSrnf*lnbadP;#q|`>cC6O?sGAm-uIVx0Vs<`kB+pVw}VEY{&CWCudO`>&bMspE} z-^!~%Rp3Di;He%8JUy_%5%K%_$sH9>k)H>A5Q7c#J8RSVpv-R?+$a(uMPH(&X=51T zY+~-*UM$zURB|oy%Nx=!W2M>iR?e4^*;1)M2O%4_9iKh}mj(cb0I1PAP|0o+&5e6f z$b%k|Vc(pm%<9vPBbwGPUQKSFRtajDqtcS)c$Tl%(+G>o2n%{L$$MDjlEvuBh&gL} zvcWBw{#=QQ-kOtZOk@4_BAnX2b&SnDsfT66F^iUrTr$a_j5w0|^^PpOJ&E0-7tO+= zRinBky|-zC*VyTp=acQQ-(oEN*}YFdK{Kcyi<*p+#SY~x?zpqesj+b@-PJl3*hmNM zZ(QU+>=HcqSNe}no!g+nuQFwDm;;9Cx&_2-#wLJIR^DKYA9!jan(KE-5 z@u{)l6DLkSA+=& z^&X@XAhn>cR4?ly*5WO{07*hA=*xf?0l_+`uQ2=-#7hkK|Hr?j#+-YlQtGRuF`KQb zTwqf@MJ_*NvLa#F4)-$>NDknO0K_6A1>5tb_^4&q6ueX&AfseD^A;bJhXg2-)@AOS zob98Fg87M{WU6R8C8|~~aQ;P@)Wu@!v$0n}?h}7%eSDvco<2D|GOCAZ9L#3{s)@D0 z+}at}#i4DTJ6>l2&UOdnHfH0rA3^G+Fgiz}UN%RdUF-i3vqGRW|p>C33= z=7t72weK+NeiVy80sN4m%8h{m75W*&5ezXIHK{l>NIwRh;8TqfnuY!&$^y2cp98S2 zY|$66v26H66yumDgyrN_&v2Kjyu1ymIBo^g_i7?N)0N$Pi&v|XDj%8EUv{O#DU5PL zUEs2~*S$T4(lhz*?%w6^fP9ldred6&Wv@IUF=f zVnvP2aM5&W7_Y|wZvoIx1kcpT*Aqb?a8EX}_9U(egKr+1gbV_tSFo7Qm5Q$ESC6tx z*LdgADuhz1ldCc{3Hk4CH}xLNaLlSLGQ!=nGAEM-+gZG9Ts}Nx3=PUe@MaGk9+Ihm zHqjouR1xGtUOZF?oJ+x6TulizG-Q%*9;13s2QjDNmYC^j?!>M#s*DEeswC^X^Uawvs!9{*!-)qaVY3+Wm+_0FQ*`QIQG{G2Cn9gZ+BDKHob0+v4(8R1sGpZEyRs+`^O47#TfdjAqXq zJ2igl7^9l5GzO{10V}bweqa)li1t!NI)+YC|8XOH4(Ilm?aAdKctc Mc#6`6+xPDO0gnba)&Kwi diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-39.pyc index f47f051550be48f0a973d161b57197b4daa86d20..fad42f65f7cac212bfd83726fede8e289ebbc357 100644 GIT binary patch delta 293 zcmZ1?vrdLPk(ZZ?0SL0C=WXQ9VNxj5&&bbB)z2=4!)TF@LIny$8QsawDQge%3fyUipE>10on*4w#g~J=j)s!yM zo$SM_s_6#g6mftEP7ncdRuRajMcg358APan2&c)jcy&b`K}=Z?VGJVNL4^0@JG>qM D0b))& delta 278 zcmZ1{vqXkFk(ZZ?0SJDaFW$(V!z7lYpPQPJnW*oPSd`*Ylv$RlA5fW5vUxhwPZq{o zlP9ukOWk5A$S*Fr#hj8_c8fJ9KRGc+letI^XvD3_*VvO8%{N%0wl?nl31LPT3loX;&A3A=BCCMBo>tvi2?Z#?OaKvnK>z7(OcXQc5Y%xa>lL6 zGTeoX{+s)_r5PC=Ca>aAlLDK_nUQ)vkL;%nrhTq zVq$$sy?OEv&~Va3J^CMTASTA69=sS+PwG5Y6Vo|-^X7fu`{uowFXiv$P(hN$$Hb~l zJ%1G%cxT#j#jG>A#;dktmKnF@WwY3!IIcf3!+p!YW-j{=JBvpCBe?$*%# zmT5cU7#Qsh^B!1~*J1D^Xa2)^7irx@-7i{2_^|vsgM5JeBJ|hgySLnkt~Jo5+lmT zxSLx|=}^Z(s z3qCmTzlNTb=SP|vCNf!In9nT5Ziw_t(TY9#Y;O>Pp5U*bms36&z;DVi9AtjOP27?u z@T)9=fj{Nz(8jAu1S)^+dP-W@y;gGJTXf590lF_wpRHp|od%9s_0$ngmdY?xG!26l zovPWe`8MevU{5^>I=)wvi@J2aQLZ+s4$E~cX7elwXiR($1 z@8`$rru(zKuN<9L3tBdMF3So@rq$JGs#&TT;8^hiH&*-ZIb+;0!_oTO z=rqr=@|VQ9qoCGB0WS`wp=fLjF4%%o!iqzK1;lB=ATeEl41!GKnP9$Sj&e6~ySsOo zDvDVVq~(Z^Ny{D)lYhae@^;s-E*f^-vMCM4 zVG*}``f+P$0v6CS{HpT?&AKK4H{}6*8aU)+|2Hwkx+NYPkq^#`KFPl0Pr^ll{RFpZ z5o38IV}oU3;a?5s-4CcB)NRa6;Zk@4X7Ovd`$oPS#NWT@3~&p5UA=o<2|YWVD`Zc*W($6-At3x_wc zwC@h3mjrM}hTe+fQ6&H^JgXcZXo<8G}>x*2u;qwEApP7;ih4wLZ<9V-+* U!L_*5-5~mmfUbkJ#I3*h14W_S2mk;8 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-39.pyc index dad937f8db6b7e66ba9e604124a4cdd007256560..88cf1cc5503b2433c847ff30f51c32b39eeff891 100644 GIT binary patch delta 78 zcmX@abcTsLk(ZZ?0SL0C=S}3EV;;p(UX)l+kXlr{lA(wdC=MommFZ{X=cejs7iAWg b1ZmZ~36nNc$FULF9_Mi!p{ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-39.pyc index d6ce14f3262e53cc7b28167459e90e428b43842a..275350d33ab44bcd823d982d4060ada2cde5960f 100644 GIT binary patch delta 64 zcmZqT>EYo{Sq^a7MJ9wr4|+IyW}UA=BDPA6zdmM SmSk+cz<7n3F>3Ns)>r^v3l&oU delta 54 zcmeC-Y2x8dRqi#KwwXB5lQ&rMCqOw{*CEJ|@H$}CIO52(y2*?f!f3Nz!a I$?I8T0lga%YybcN diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-39.pyc index 8017d20a650e0270bd1d250cacf7ab20611a6c47..69990d9859f277503086fb250e8dd38606882fbb 100644 GIT binary patch delta 1039 zcmZWoO-vI(6z*(kQ`#=$Bl0BIi4|*^jOgwqm7-KwZq8{{SoHsx`xXFI|<$Lda^Yh+*&_C-TU6z9$ z{^Slm+zCCEnpTu7DPSc>4a+7Am|DspNf!&)v@K=%x}A02OOHzj)R0ArG>tWzV(gYu ze6@%z8)wv@K5uEeF;xcsFBCEfE$qkG^YB^J_uyEAb3~SWsE@@e*HAy(uAGYY^WD%v zfEEs}pB7CMQ#uSv1R%i0H0Ctdd_nR!*Plqc;S>b? z=eV-%VfSLa?0c=xF(O})lH!_MuIc$aS=AQ!XI@X|cv%u$yM<=5#b1>`&Tj#Hsat&cYZYgLJ_q(HI(Y-{v6eAsX>!yaCU5F)bc%|8Rm+fH!`ZcFYq=HN@Ltw4QC0-X$8Zw z40BPf*dv-yO}&8CAjNi(ni{u=*V8k+#tpCVc`}H}jTeY$vFpcXnq=6=)|1E8;3_q2 ztSwo@bbZT9#4u?HP9ZuE?H2d!dM%q$7!s8Y$Ghq=1jM-X0E3yKwIX^y-i?y%b$sW< zD2QVKFa&f009rz40A>L+fH?piAjxibMVyyyFA!4M&Gv5pDyY|>E$or6guQLQ;=ch> z!fEShM`dfAyM9fafNro%=XwY#TyLH%^0IH8htVdJm4U`}P{Wq3+eW&8?JUXA4e+@G zunDVnP>b_vBThvZk)#x<1ZaKbc>`X`5C;tO#K7btnGtX=;p;ls227r67p3N$Ee0X={yIbi2t;+O^59&Tb;2 z=%E%B(H^En!BbCFJV@A^SI@;m!NXh>58_o1RuIH_+s1+jF6@st-+S+yVfO7u>AmEZ zJRVmAe}25vYwp*!_L5M>vLXq?5|PtHsbV2}bIvfC?L|{RbL(1#6tHLzj9C-G*DF{z zu*_UiUKh7=%meXG%B^aoT+h+B&7&w~ws=B~C`IGm+bB(6d2``3KL8m49OYmRQc+b* z$Qe+4fFT;$x9J(>Va!f~pk!#Y^;_G}p9-tY56f{=X#0em6Fh!tBSHEk;CGzki`54D zEYfGHzOM*P(V2iRF$v{%sN1z=dJ%*vz$Jj?xnrC&*8*`{)XGC8cZX&IHgyLPgslqt zE9f&@4}L%)YYpci=K+7&=1p(MQ5(8IABKadVCFiLw$K%*n*m7w=#b5|@cRF3u}LE* zk=NRLnw!)wZWb;C70sVVz9S!N%?@UJlYQdA)X3?yIMAOO8_c8`bw3+eSnXIA#Bl&j0?7d`1M+|ZKn7qy5in`ix;79$z+!jOaUYZiwA1OM z8{N~6N3a|+kN0$=md8A14)F$23`~}(8o%R)YGyBKv%F<99%@|S>nc6lv!C_~hdY)a z+pHUsp%lv4nA2pk%q8*^utIBHezZWBgadmPxDc~tGS(X=_vjm;2i>Aygh+>Vb4~-7 puN9RNCQfM80Prg_+Lajgryz1@`K!2K5HI8w0SkNsA6-qH`VB-m6R-dP diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/__pycache__/__init__.cpython-39.pyc index 39c49518d3ac79df111d7c75676b3732e97e9612..f7bf991ddf635de616711c826b11a811e645c848 100644 GIT binary patch delta 58 zcmbQkzKoqak(ZZ?0SL0C=WXP^&8X0*pOK%Ns-InySzMBzmReM-?~KQ}ccGg03ou_(o*D6=e8KcF(BWHTGn0!9E| C6%R)M diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-39.pyc index 201c5709f6a0edba9b0c6dfc587898137e12fdf1..9257c9450ff6b06d76ffd8c5d72d01b645f1c08c 100644 GIT binary patch delta 17787 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 H;<)%fj2sLP delta 18399 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 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-39.pyc index add191e687b04bf43d477ab924be1dfe90397579..fac51c510ba49a621a52c2f0d3a6cf75d75aefbe 100644 GIT binary patch delta 63 zcmbQtI+v9@k(ZZ?0SL0C=WXP6WmKrw&&bbB)z2=L_k(ZZ?0SJDaFW$)Q$|zQ*yd HK}_BNo=y=j diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-39.pyc index 2f3386dbcbc0d1e8957214e8e18bd22c66459340..bccc51131678531f06c73025c558b7b3618bba45 100644 GIT binary patch delta 65 zcmX>db~TJUk(ZZ?0SL0C=WXQnW>cuq&&bbB)z2=14*rWF$arrH%j delta 55 zcmcZ_b~=nZk(ZZ?0SJDaFW$)Q%_df)pPQPJnW*oPSd`*Ylv$RlA5fW5vbl_Hi4x_OUJhpoF3-s2H+VpO~LZbaC@C(J;;XAc@ zr&euMJGI8GJrbp#xneBtijoAt5`aMY;8~QWrC;dwbq5V! zA(EkW{&s=ob8gBB4#s^;A1YSQ@!vOfLz*KQcqh_#yb#Jm7zS9jzwt4&+Kxg|Tg{s{ z8uiXjb9b9W-Ry(lLoBPN(bW$~4A^Nqz4#to`-|;00c;LymWq$|52Sgo(wTmkmnV^m ztfBMm2s5m1?QGBZap0$@J?)R39+lCW$K7jHTeIAV%k7)0(#Io9v8FFR#5ic5 ruc(^$d(D#y-OpYS8ULTMWco5&;AHoalpt~XG20DX1u>aca=X6)MO3br delta 881 zcmZuv&ui0A9QRe1wdvYrNz=|0tDSC|TAHF=tAb!zYrDgoa|OMHm}YCBOT$a5&cpEN zVJF|+`w$9}tABwP&j!Su#lt`b;>mnply+k|e8~I0@8|RV@pI@0ze8t48WhZHMi#&w$G_AO}D4+4EwIBLJ(gBJ<^I*1LeJ#cV!+( zR3i<4nE>R7A1Rf6WFH_bkq!1KL+>w<5t~_*APZ9c80e{e({b?(1Q!4j06Fgm%b^?o zEcCmw{^;RqOKq>OH8B_5zK-oFC4FFRncH{{vZ14tSDhK5`zILTjKGL0hN~;Dy4&(p z*y_n~agNG(`D76-`AJ%|zS3?^)Qmz+P45}wk^(v87;k@8M8%M^*{OFXImv+2ALv?N zaa_$k#XQcHf};NPz&0&&U`=fB`u~{(!tlQkNB;1I{23KSO%y9fG)lRa2EjDAsgA0XU`uXas1rq zvXYQdASJ1g4qq=e?7pTO;c}*MomkRMkv`8;-Brj)x*Dwne3{2Q`6_KO4?wI!n%T9# DnkK_d diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-39.pyc index e1645a38683b633c3f7814b3689dafe600f677a9..1555d41ff987b188374a2ea86231fb131fdd1a33 100644 GIT binary patch delta 55 zcmdnMw2O&5k(ZZ?0SL0C=S}3Eqfo7%k)NBYpIww$T#}!bT2!p>lAm0fo0?ZrtY1)B Jk}+{_F#y5365jv- delta 45 zcmdnRw1J5`k(ZZ?0SJDaFP_LfN32jkH#H?QQQsr6D8;2Hvn*9VpfaOm;_+etHlGh} diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-39.pyc index 9d08adae503c2f7a78b1c08f372de85a2e1e085d..e852d526875f0555d6f74da49c34ce9cf9c04f61 100644 GIT binary patch delta 448 zcmXBPOG^S#6bJBbBfWIQaWo4F(x4J73EEXEVYaZsz+PkIW4bn>rra^eO&=kVvkxMI zpjEhRW0dO_?fd|Jj^?j-@#EabIrp58a4&2x$nw;PwaWg-cY9Bozl#{PDvy-Kwb`hZ zxG*D$ntog5Hw`mVZ#In1pY$p*t zos@}L+ExzOIklA*%TmA{WSkQ2{8$zliuJ%ZDvI>w&al{U6Q?z`px~R3G;AO9X!NZ9 z`jOP1%rxtKM~IpbdnhvKXrJ01m8I#$v(ArkdIC-X+7f3#2bZ7(I4FWRFaRd&%ekCh jDVV0tE0tVMEaGB79?=reDC!L{jSTODW!LE==k&@yr>bdb delta 413 zcmX}nO-lk%6b9ferBEQo+SD1v=(z!aLbzx_!HR8X%t45gOU6;*pNAQPExk8Nd_ zYJ9KUQkCOsl$u;n>rU>g5o++8TH>-C9v5j&1q}r)V$x`4EHUJ#;HO?inkw}=)|L<# zLhLy8Xqp1j(m%^cMeffe*UE^8;0RziaSTjgffi_j25?tCMJn>V7V#R0?vEADX)&s> K&~6+ll=%Zhx?cVO diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-39.pyc index 0e040a9f8c2a0482521896ff784218235765428d..a4ec1a3a24ed15977fa57a3164475e682e904e0e 100644 GIT binary patch delta 686 zcmdlWx=WNhk(ZZ?0SL0C=WXO}WD(r%(9~Bia;`oljpODGb&Dg#VkAd3X7uyk{*z>AcznE5!f^<10~FXxR?bqU$CI_%7%V_|`N|}MgqiNkxx(iBo7Ab9> z$mYfv7sZ}ekdauNS{%iN2(u{GytLAsoLj75sVKI*)ZBuS$|8P{S!N5=+wZi*j#q6_+Fyl@ym}mShxZ zgEgTV1U3?En%d-p9HNYB;PBYMDKVLc)6WvsY={8}MaW($Yi`0?8tXD56!gj0gwOF@C<#fcJW?p;zjq+Yus3WYiLEKjm0DZ?)1aAx|y z&?E|rXqJSau8_oj!|X#Y3JJEY#Dz3FRKh~yrmd_AMea5CYb8s!xX)b>m(6O^Fu3eU zTru^=zTJWW>N$$w-f|N_H*FXr*AO90aA%LuG0K+Im2bN`RipW=BYh8d5}lkB3d?Ag zicp0LA1V4ec%$4$bRR%J1vu464^YWp Jz1f*B{RvC^h1UQ8 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/progress/__pycache__/colors.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/progress/__pycache__/colors.cpython-39.pyc index 7a448b5662dacd7879b8e72a8c3ba6c1b55b2b51..0be20afa89e47fa8e7ed334d51c8dacea305467c 100644 GIT binary patch delta 58 zcmaFL{hpgUk(ZZ?0SL0C=WXQv%dAkQpOK%Ns-InySzMBzmReM-?~=-T(jq delta 48 zcmdnTy@i`Qk(ZZ?0SJDaFW$(#i%~3BKQ}ccGg03ou_(o*D6=e8KcF(BWb;$To6G=c CRuF9f diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-39.pyc index 15a37dee88f7326599dc25ef96fdb0b297c68d9f..45020627b221902aef028e8599c0a399d6c50317 100644 GIT binary patch delta 490 zcmYk(%SyvQ6b9gqRjY}qf5)!Hh$XvBKIS9GC!H`$bsPTQeLCY+f{UHK5>viJh7 zr1%CtMP5J<*DhR$bE=?Oe31X-{0y1L+;h%!Ez3ygr#1WVWWJ?{qdrpC#c7>g_L8H^#KZ;YGov<*by85&=n|(lU>byElr{Ex z=a>$oi zvKSXIPFIAWfL%Y6d7LaFIW*4pTUjV6gsxv|OXiD`$Aid~P*nGpO_tS*wLszV0G>$Uc%m z4v<6SNaKtMDn$QJ9AkE((Fc&OY>TR=>jj)*UO~Lpz?C%lvd?zFpm6 zre)~I2AGFnb(nr}cM}Ld*(3P@9WN0XkHHW*QI}STCOoM}!hs@7gk;5(@?H*Q-}1}N z4s%TpU<3=Z5kiS|Tg(qE&*dih$&VtWn47_8&G zfpgsPOlEVaps6A@QI8tF1zWh?M(iMV5m`hHQAg}W2$P&~K78Rmx&}Ih2S#wqo2}@2 k4hJ#urfL~D#rzEOgzdH4mfMDNkxXe5|3Ccq&9zkb2V-b)9RL6T diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-39.pyc index 22ffd324edb7af9f6f25d4bdc37816adc7d8aa96..558429ff5b52f55f74ce9197921381036006a76e 100644 GIT binary patch delta 72 zcmdnOvX6y3k(ZZ?0SL0C=S}1eWQ^JvYsRR>4HPH>5x=VSGxBp&^|OmIi%as;Qj3c9 XUGkGlb5rw5iuDUBOEM;JW^4oiopu$| delta 62 zcmdnTvW0~^k(ZZ?0SJDaFP_L9$argGtQn&M4^W^8MEok$&rMCqOw{*CEJ|@H$}CIO N52(y2nY@>=5datG6662? diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-39.pyc index 3d097e350415f4827eb562d9e78a483a0b88348f..c573bdca08985a97fa019e3754a313b32ec32a37 100644 GIT binary patch delta 76 zcmbQwwUUcFk(ZZ?0SL0C=WXQfXHuxw&&bbB)z2=l=pPQPJnW*oPSd`*Ylv$RlA5fW5vUwNNNk+z7 TlUrCE7zHOEWibYlKUoX_u^JVO diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-39.pyc index 2adc4e7354f49722e907f19b316c573a1e9fa598..8f266c12ce8e27192f59d42d41b6ac5099be798a 100644 GIT binary patch delta 897 zcmYk4&1(}u7{;BZ`LJnhY;6^bS|vueR)ejG*u=D;1@T)H?V>L0W|Cbt*@-h7o7hOJ z6f06ZI8fAzw&KBq9%K%p-t^)J-b8Rug5brA|A6AWn~Lt?x6jV|%=6C7&gUugbqYoG zSgd7XBTLlR1}7b{az zt!XCKbFw#W)cJIGdUqaN0dR%sfP8sD-zxk1Gwd;)7MK?<>5g8&l;*&W0eSJO`+ak$ z0NUgqd*+ZTto6YFI?hR=3r+BAiJnjus&(-s(HB5A|FS9Br^^u~;4D z>8ymh(qbCqTR5kgu3Oe9zEHu;RhL(oLHi4C2bBa|2HXbR0o()l zZL0i8dgBHrzrC+wor5Y|0xxXpOm|&MAM)Asb~MW0rYF%9-=9&@41bhSGUMPv z*l*{B4YT6dI7jb7zyT-)q*5bAGUneoFVwgo^o(fP6GiA0@5&AgoQ5f90mlF~ zz+dzXD1S>?Q2+Lj=k=@>SHpyDE9qe1Z=U%0PFDua)=!MTNT%!KDZ;U3$;hqFH?WbI$+Ydk#0>=E>)I;-`T? z-3Iyl{hqJ*tL`>qP*;^K9Xv>xa)4#ese?ymG|PVC-W>>wV9_)SskCVrYTC-01{d{C zMWLyy{`4-Q5WD#=sFQL-|BXCjLVAfbBkIfE{9Z9 zwgo*4u-qH+%%YsLS9|+iqzK=4gxeKaiTK#C(?G-#I)wUKNX6dMH%^EGmm}Rohv!4h z_S49Zn&_0YjIoTQOm0U19HLc1cz9YqT9UCaQgHCP%!++Pt0Z7jNG_>Ta#|uU6q^Zov&CHPsS%hCB(ZmwE?;{>a zME0_4sGaGWP=yf}5w{Sx5%&ZMv{o|ms>1Hz0f(^Vk`Kt1QTYnywDSiN9!;h4 ziCD^R+2*$3)DnRj7 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/api.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/api.cpython-39.pyc index 8306c5252fe822a9c880243dbc5aedf42b728bda..775dd96b3ea9fafb5827046645534c5b8bf78043 100644 GIT binary patch delta 261 zcmX?Ma>;}{k(ZZ?0SL0C=WXP^&#h3bpOK%Ns-InySzMBzmReM-?~`wvVfSZpb$_n6C}+9lIAHA z+9blvBrXhO7x4m#mCQvTeMMja_Q?w+g#|@{{0bn3=@6YHVzs$K>?|WUTvw48Sfw~n yRXdVO@yUUFW}8<@a4`x>0EMT)r8tWuCLfhF5(T-n2;`z7kR?SR{XiKWDH{MLf-!{v delta 259 zcmca)a>9f=k(ZZ?0SJDaFW$&~pIaO9p|FIYFp!xE#KlZNf`O+ zGZQaZ1usx!C36wW`_ZJCeBSn9q zQ6sCIjnuDkPh=wZw3PTR@_P*Pm53(AH^#-GTyxx#K`bqCLf%Z5h-!LBd>hG%b6p#$ z0i^qY1kj=rhobirNCy$0dxW;-{)%2m?QaSWHlLI}DMdciRw`!8m9Z?vb-TSdhVoN#kA+Y{Nvcr z@GhjES9we(D)Mfw6djW_Gvd$KBW=I&`2M9k6aOJKq%=P^-a)*! zHSv`VKjsR)#S zW596OFmuZUX7kc^eiwBoRbJbCyRk0|Dek9k{zu(b(bgrHbgK+maC6r#pjLAIlfZyl`Ae?Vy!#1{-{44 z(q0#jQ^QB{m_HE27FN?6@r zWkl_j`67J_b(Af&K`rk>LV39Xq0ULQN{@=qGJE!}A@vb}HRV~GL}=dl^E!6M-szvF`v!u8kdjq)Tusn8R5?X z4^SuckXXxJ%-TDrXUcP>@|-hw{&dMXHZyz5nV)^PRGywGmWsC6mP=YGsR<1K(q*#1 URqIv#ilVhpyyagegq@pw0{iwozyJUM delta 1584 zcmai!&u<$=6vw;%v36q&EhaJSCUMd>BpVFDhNPjOwx$ULQqlxm)I!i|o1JEzI$8J4 zx+NU=bwG%o&>+-9p-~S=J)&GW_W}sG4!!n5{{d71V!jh(I~4{?`_at%LZF z&X>e)yHx0Qr@Oa=hqw~`{Ia*@8_nrM`k#k((y~N1V)9=!}xY~Pb=Yoz4 zzprQ>g~2iLW#8BbI4`{c;J7l$8}(Y`*rdDBTxU@b`ZC_6I?cdn7I+DG89=Mc9@nd{ zhE$7!by|Y73cLxNfj%}rBTcpu`L$JEK?gRm%MtD z(Ocq7eq^66<1%8Q)-orSdUM-b`2&Wd3;v=KI&qyX4Z*;?aM`0(-dVEkyN}v2;{}nj zi$|Y<{h-Y7$cviXT?y4YX$7JRBBY32Y%(6n#JSMlRK3911)5YEIxjBTPZ`I>mVGSq zJ_I4q5Wm?@N%!0k_8%%ple?HRGT!i1pa!vqjJdns_4Z7^Vay^QnI^^?;Ra{AXwE}) z0&#R&x>6ng1%=M#Q#d9fR1mI4(yu4oqJ}x`~brHCKmOxe#G*~Tk zpEs~6i#vnPQr8ipv)4K6baY~Rn6zh0`*G?ON=t`@TPO@4R!h}>dLY#yz5=WPx>cve z^}@0t#UF)%d6_?PYN0y2P<5+k7iZnqPM@s4;x1NRuM!5LG{bXiY$eh&nJ~2UY$5zZ NM|d0IXycegFUf delta 63 zcmeBSZDQq4Rqi#KxbVr0BE`52?F0tZl}2t@qK*3V5%$xPJuNGwWmDatHM O)eor5D48tFln($TQxcB= diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-39.pyc index d165dd275fd74ec2d9844e7e5f2171659e1c43b2..a7b28ba10eef4c916a2bd678c5a9f979395a7767 100644 GIT binary patch delta 165 zcmcc0bDxJhk(ZZ?0SL0C=WXPcWD$>Ii7!hny2X}R9A8jr1f`9mCR?)vOGUAl7Ukq* zCK(k819e1kCgSq^a7MJ9wr4|+IyW}UA=BDPA6zdmMmSjv`&bkf&HO4gL delta 155 zcmcc5bCriXk(ZZ?0SJDaFW$&4$s&G>CB7`R=oVXMaeP6g5tKH*HQAaaSn3vgX;Ds2 zW|C2nFi^)W&gA_3?95c4z^%zESc({LO_pZWmbt|TQKVOtT3DJ|Tyl#gqokyuND8E5 qauTbmf(4LO1R{Rr=;x-UWG3o+Bo?K(6lIpB>IYP2luX{px()y^QZ<7B diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-39.pyc index c146d0afcc706921b14765d7e232cdddeea158fd..ab01eb11010fbb9801fdb801fb1a09105183718d 100644 GIT binary patch delta 1509 zcmZvcUrbw79LGIvxdl4r+}NzLK^+FX;@072GNniXOHdbJT>)D*OM82z7utL4@1BYc z50t1g#zkgM9Q&jAf-xH|Mz5G`F(w-0qc2O;T;r238clpNzLDFJ9kyEOM(S5EiKJ=$-jlR^-luNH-r|$d8??07r?N&^@0v|_$f;(7j=`{;ZlX? zo#lqR?_nvix-ZER&TsqfW37`i`~&&3Jra!!a4vd1d!3%($BGpF)P9b!Q{wH;Jz^>J z2g{1EKPajX{1cd!LO6=Z(Az5qe^)e|>L_tGI{j=HY1ID;o$nq@v6^y@%tpGdhe$Y% z!U>71Uf3o7x&EA0%owH(we`EYzhblE*Y5qbe4OAztxPd6XdW|gVk&1+aP#5E>Ir*$ z-fx{kqaEqAW|sV}Cr`RzGW#Wzn}X6Hq^FBzaZW^wJD__8l}qJTpaVIf{b*oc=9i-?yISV&q6 zUd7Qg;!VU`h$`Z|=#Cr+P*tg*Q(`AOvdN=c6aSO9dX=oEcf%PIhNB()DbD@UqQ ztLRaDiaqBlpxfmFPl+?p18hbtMf=%|b0d0^$xlXLsAKtx6pg^0K6wX&8uOf&EVEF7 zi)eHK!6eicKs~&RxQw8{OE{uVqE=hO>3fKE1X)l*=%WT)uVHf6$Bm-yHjAr60k$Ew zhC-b)D8`Qu97bS->UEW(1-4!QTq7m^9%`2#tb2zCS;|Qcdpz~4ZN;L2DGZ{b&4`<^ zgHrZ$EY7x^BO_~U;xjaBg4=fumQlSa;reoh#$gNRbgVlEIR_(K=Jf-wmn@E2zeYFI zmMM%*bli}SRL|I${3XPR<@vY^BT UhR_M5a75{#KkTMUG5&P)U)UsqUjP6A delta 1422 zcmZvcZA@EL7{@)Oy?~|eg$|jKS2x@hM`?6|1EjzpEE-lCHYl)_OM9gk+TQxyQ)d@H zj49FivXMO>7TAkooYR;&m;23-C~+}<@GaRFb3duk_`$`*m>B(_@jRzZiHlA8>vQh; zKhHV$`JdAjWM`3iHJ|V9yTs?uudN&2W1gCHAgw11EikM>;s6-W>Va@R$?emgE!&ub zD>YGe*#5m{C-WZ>NmsegRSDn@nkigv_S60Zr-gb<1tRn1~&>26Gl1qq!VmJE59z6xZ8tu}NGG`a_iFxZ`Fv52ad;lFKGE zu9x1@mgb|_DMPs6+_j7zjgRs#V&pG=pU|@7wK_1{9hW` zU2rjqw>x%LIThTD=sX7*QD9qVHJiZQowwK`{?&Ok@Dhn%78p@IaGD0E1e{8q1YJuQ znK{Q3dCH70NDaIykHrsMg#kydpToK!OU@mPGm(51~*E#g=ESJ^oPM!S2( zE?2s(he;re9Vm%MDUx=V!H|fZa@za6CLEG4_+-yscHYkSTxRTftnIzVF5qXq(WV)a zR*vPf`XGP_Ag_jOmwVPUQ*Z)9q5FJvUK|BPRP(o;Yc9UnK+dW`GoY)YKqJMEmprhz^-Wyc3x zuHvQ44~D#@3k1`6bFf+bAN@QSVe1(5`|XjT7g+csTB#ByX;nAjB;i8=$DJ_Z9M)+p zn|V(k=U~j{c(Khzqavg&kDKO#p<50%4Tl>x#3R);G9tcXYCUvO2{Ie56K>%0a2Gp+ oUkpFdL08|YisUl%as~I~H91K_x%u-H$@WZ9B)7AHeFrE01xEF9%K!iX diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-39.pyc index 5744b682ea22e5f0df0436f3fcdabf45d57da475..02d312b6376eadae4f2f290c155669ea9630ec59 100644 GIT binary patch delta 71 zcmZ3cwLyzJk(ZZ?0SL0C=WXN`VNs~k&&bbB)z2=wM>gUk(ZZ?0SJDaFW$&4!Xj3npPQPJnW*oPSd`*Ylv$RlA5fW5ve}+x3qNDj QOV diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-39.pyc index b6924a99ddc993da9c08eb04fad5e84b43477968..59900ec36e64d634b38df04f2131418af2630077 100644 GIT binary patch delta 101 zcmaFP{*j$Kk(ZZ?0SL0C=WXP!V^k>B&&bbB)z2=@#TPz@$y=P*kF$?ePr0HduU A9{>OV delta 112 zcmey!{+yjVk(ZZ?0SJDaFW$&q$0(MqpPQPJnW*oPSd`*Ylv$RlA5fW5vUw%rY(}YD zoEiD~+3_ifC5gA#vda^T(u;4gfP`*Mj$?M05e6FLr^#}QJw84qKRG_Whyy54#0esV JCm&=s00377Bnbcj diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/models.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/models.cpython-39.pyc index 87e4f5c23a4ba746b411a2285f50f8ae397a9100..5446a785d775820f773f5314099c587cc7362063 100644 GIT binary patch delta 2853 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 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-39.pyc index 39e1b93946fe4c9b9968708f2c4cf7901886a4da..ce8774a0647c37d10c6cf79338ce4b5b8085972f 100644 GIT binary patch delta 2571 zcmZuzYfKbZ6!tFcF0#B81)&I$8dj~Vi1?`T5|Awj6_#SAZH8rc%5K@+SP)-+9QVwyf|)T9q5X%qjnzuI5^^hfVGv#{+(etevJ?s=bc z&+O?lZ1xOu`Ezr#7m2@-vY9Kc*BzDnJs~x!ct#+s>FP@gXr5LzkccWVUGu~z^br5p zaid7e2W2#&Xu7N^x*m=VOMKK>UMS^76&O~6DejE3pVb);omFggop9pLkaFiWL#jHW zNx7P$X<;=c(-CU<&FxEg_u@*ng+K5vHC|i1ow04mH11}fX07#TBnukFKgp>^f^q^P zk~5}^6OoOaxF0knC}krvN#_JY{uss;S3#GI%Q=Y*wwXU!;B#~fL(sz~3z`d>kz6dm z%n(Ll55H4zn6>kPLSQ@j_k|OE=oFerK;!^>@z{&dhu}l#7hvX1gcT7-GEYs)^9TKL zT>*Jy+z-Q=lo=AGg#jTd@#&)KWs=JZQwHJJbR=WucZy2vJ5k8^yQs_NLXwog%Ug?| z+C#Cm%oabiu}OZaq`G=Ro>GQ(6xfG=6^1H=L;OL> z+J=-LOfKbzR3sNw8Pxq@MT1EpAmt2A#QmBk#|3jj;?I;m%|?yGr3uEu{LzZ)>Xbc- z`v@9M3pB)A%i=4jA6~pZfB*=i2qFGcSqa<9|0;VzAWlhX`99k&%19LgW+r7%y|B|* zQBnO-E!8PAE7=sy>f<3aJjkzA7&6&8j%P}^2q}*69s+ee)$l^(4I+>Q7g87lWFVXn zVA`W2gE0zsM1I4EMC6tZU86Y;nL@Bzwvh%keI@6u{(Ia1_j z3sU65L2nHXA_E;SJn?{dzSwl(+t^)wEW6VR809G5G%t?}-)23Z=Y)>i3Hhjc7U3MP z^i)pb1Az?)x&ZewE0B~IvPfx=KdK5jrE2t|B3ib(NDWNu9c7;oB4#F*NyBQz3VLt&>9@yEr&hb5>lA><&?JYb#RMT7(Vc4JM)^MZ8eTE(Ed zi+G3mSPz@rJCm+WyQcd=HyOZ}DA6Rq%otW;An^@l%MD-CQ8tM?4_*=AlZtxV_V%~+ z`TFEt&2meBcWYOhl((zDw<~paXId+WHVf6mCsf@z*7l$ZtVDww5pbSNo2rQvV`E`Z zW7bnm>GmyJw9fkQhWBBk*La(@tFLpZb$UHoGaY08i1MfQ6@B5SLLWWroblTQ#{`ywGLsL|I>a|?AEip zUns&1sEOj^OJXN^e#exH68jN_zvGuWh9{39`3}OnsNj_4pc;^6_yJk(Bb-7wgK!Rk zCWo5!2_7#Ye1`Bj!c~N82)MUk7U4Pq)&-^!ZX?`55MlA3%L>^PKj+=ari=&Pqf8vu z?a2G|t;paOyu;cvK&NWQswk{9jytZqEo!~QF1KYk3B4%E*u0wbz ip(||wDoA$gvDBeDu5{C(4!x`dbl8fVDTI5%SL9!fj*1-s delta 2586 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 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-39.pyc index d6204e20768908e53729671f43eafa9393bbadfb..196a31bd06883bc242859c87f0c10b7531725b4d 100644 GIT binary patch delta 360 zcmeyW^k0cPk(ZZ?0SL0C=WXPE$f{7KpOK%Ns-InySzMBzmReM-?~CpYk4W;C80BA~%&I=NOr zT}2C|N*hGzfCya>0Wz>i6GVuC2-C?Y1Z24lK}@hu^d^505a$G0?Wf6Eq&rzaP#5BG PuxogMVInd)MoIa}_FjH;9Qc_y>T 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 NB8U?l*9mQFcT998cS;)S z=~Bo_e}2L3Dv3QBC5|9235g(>&l9sOO2gWnlIz)Q)RoHmPx0I~9h#!M0-^yZ11f+j z;CGF0_lx;yZos6KAEWfOd8D>VQq53s;jq)(GSlPs_Du~UbwC4Pg12~Z>ET2W8ry5G z!|@0&?yL=_4&eV5pfx2D`Ehs{UC~rc)wP*=*j>sHbN;d L@c?{Wm8j4!ggPm(p zHlV^^h5EUvDVd4-9*IRME=8GTsrmtx86}%Nn6`2<-kSW6+kzXU46L?@eX}DE3!5P) zP~a91lEKBd1T*uJ^K%OlOEQx(b23XZQ;Q)wzHl z5={<}ATNjz01?6t+QuL3g6i7xIRhoVCFR=(F2|l3cEw=3P#G-T*$4t(W zG_4l}X%Pbv;vhl-q?XgQB0067Br`wn7GF|gacX=jj9(-JQX~f=&|Lu%lLQh4KwJ!R qI|m~R6AKdu3s}@ollc}~eo|Iya!C;*OexR|pxcm4VxO!dB>@0{&}1|K diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-39.pyc index 83278aba0f010703bcb15a26fbcc4793f7a38eaa..5cfea674f59e0ad4c4b9c8548fc93ca13fff83c1 100644 GIT binary patch delta 58 zcmZn{nkdAb$ji&c00i06^EPrvGAdN-XXNLm>Sq^a7MJ9wr4|+IyW}UA=BDPA6zdmM MmSk+MV(euH0NUvii~s-t delta 48 zcmbOz)GoxG$ji&c00ckJ7jNW_WE3mZ&rMCqOw{*CEJ|@H$}CIO52(y2+1$d|%MJid CZ4Vp( diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-39.pyc index 84c80bea92f1f18289b54c52ac38182eb2f4d2ad..9d9b7808e6d55a78d3d958b1ca0232efc609d51e 100644 GIT binary patch delta 650 zcmX|;J8Tm{5QaS$$9Wio6L1`hhm2%lpAvI8ND*-=q@)NBiGs?_$(+~mVf!xZ-pK|7 zi4dJFa5B7%mR?;~WZq0cE_<8CAtmE$JxEDRY6M{DWn2E(ZdO z#vp=+APKL+`D+lL2%v#bPvD%&zt|eH*em@+J{=)={T$y_lDG9`ZrX-^)&MgP_8qQYS}A${Q26&K3;fvFyKveTc69(2#1GCBGK3|< ze!@klq%00=ZPeszA`|R*OaMy4@lxeqEhYSP8e%DOSUu={#%T zc*Yv43GY1?3b~39QKl;J0M|2*$L>>(D0fWTSq#FKQ=}qD5+sU{iXqPDrr3KlbNX@VlZpRBwzMhy+cb`-5PdA7L=>QyItq{QTdqDR Po1zY68Q8>Y^H=`@O2)Gz diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-39.pyc index ce19a95121c3b26bc3adedaf3199940efb0a30dd..f68b926bbe12ba8a2ca83be7c389abba136257dc 100644 GIT binary patch delta 424 zcmexi(PYV;$ji&c00i06^EPtdV^pZr&&bbB)z2=13Z?;mC{8=%G_TM%IkBvvvNaRaHS$?k%uq#Qt^jvxYLd=U?b-~|y* zleLBX8J#Cr3x&&Cf&{FA#4Yal_`LkQs??(V`1m4Gkg)yc_d>gv#4SLwEG3l%sYQBV zW)9F{MIMt6GKn)4Sx&ww+RW%NIaW-a(Ry;LSR$i4NMiCoF&_cA*+s4(;{+!E;g*ng z12S`gxESOf4n`IZ4rU-^XJIOGn`|H)vH7WZJEOQ4P)?Jj2xN1SH;4dPToeeia*kvi zn-yGy4eb7DlNU&;Ox_}>#1Rf;YH}6XOy-u+;Rd;~C;&u+Pj-?q0|2}fX`TQ8 delta 409 zcmZp&{9(bJ$ji&c00ckJ7jNXg$0(MspPQPJnW*oPSd`*Ylv$RlA5fW5vYC^~l$-I^ zW_#X0%wo1cSCv|nA0J;N3KDkM{8MNblei^FmZhY!Ahk#j%*@FwE-CVw{83DT6{Nj# zGM~8eWi(Ozsy;Wb_28N#=%IQRF^3UR;*ZV{)yyB#Q@7=fn+C zlf#9rH@_EeXB77V3TUzvfov=C1rZ?2ih@DbFj`GsCK<;-Rgx-`_lYS? zekUo$#t)N}nY>s^moaeiMJWmCAfR9;5Et_R2@XaUHV$SGWML`_n#>}-5a^U;((-J6 nAgw`@PfI&-L;{(bTt&8%MP+ojK~5|J8Br7oG);VRvWz?cfK6vJ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-39.pyc index 4c364a457ed2116857a3080ae0538c50dbb4c99c..9a12aa8d037efa0271024f700efd2f228c85a78b 100644 GIT binary patch delta 55 zcmcb_c!!ZYk(ZZ?0SL0C=S}3cQE1f9$j?pH&o0U=F3C?zEh^S`$xklLP0cGQ)-R|m J$(R^h3IM^}5@`Sc delta 45 zcmcb^c!`lak(ZZ?0SJDcFP_M4BUY}To0^iDsPBlaj( JWK8_i0sy&H6CD5m delta 46 zcmeBTZeZq4z^ls&>PsHQ8G>w%}J!r}(mOUM`@+SQoE&{i3 z3a3MMsPCt4a>Ym?b=8zVUu;){+0)dH{6BmqDXnxP5!a-QlI(TJ&9H<1jF8J9*8pk( zQFUTkw=mTV&j?|xrbvXY?}wUpJ0k<_lTM}_M!+>fXq$~TF_s-a?a;mc60BA_bq;&CXB zs*#F79k*iI@>o(U*~P18po?Wsjc27k&Zs_ zt7G%;DLVtx(*U%wx4_EK6K06!#jes?tn{c~=Ff8VLOh`Es+=AgfymcI!R!ifQ*woo(xkQvcqk`LipucI}u%Z_&tc4=)1)1MbH0$Oi88VN<7FDXasPKed@{rA6@b0g2(Kv9>;A}xN5=J>!GTc3-cj0HF;t2Kqtfu z0NPp(1D*xE4&cs@lVrK{)($OXO0EnK9Vo(b$E8klU?weRbA*;TC0rL&&yJG=!;Lvu zD|3|=(`3-prRJYh3hmZ!>q`dAJaohE}rMXwJ#ciomh4&fl?~sz{ z1Rn@<=q;&fEnr13^Ujjw7coF)sOnw3fp(D8-_oP%W;naz8;T zD&jSstDW`Djh{o2aobfVHs!+oZPRNw>PrB2%@;!{54DweMU^h8>tJh?O`ZiT13UoW z9_%E^N|$;f7PfQqDwc4)u>`RhTO%&skCR=%O`&D;iMK#FDE97$fu>udjJV_7vG2jIN z>R`FdWIPhvMs#$eu~7KcPmSR`e_AXUx4%FIFx;y)HftXr{u8l^)9nlCE{_Nn?_4S512d(alu9-eVRkRlti0yeddiMV(WB!=pfX zYs+`s<>ZD~pPer@7k;1Jr`Y2T^^5+ZJQhtqJ++0gesOVHN#-^s=Fb7Pi|dW~!ae=b z67u9(@DL>4r9e7XC)M!=h-}yO2!9^2V!dK`dXYl4Tl$mfoi>&d6*KDC7SS=|&D1We z-VLY)3QtGdzLbf->lDra3 zvVRDw4l8a8!F>w=u2n+^#G%Q{&<^z0o8Q|5*Zzt$6vgo9zz&oz@L zWqPFC!^%gM3a4Q8DaxC{PlAyGya&J$IGw0hT&eJR$fPZ#ixpGyMPB7%D-{PtTV>NY zi7q))xi*EyqXvtsey26X&|>I5R07&0!^`m{EpN2mE9;kUU37=rl58sTR|Cz|=YK1@nD?9pD3; zr6 zRiMD@wlXyjj8On>fhhBH04fx96tSZyi=7v9=C7o|%s+&XoTg}z=VEmJPG*XVs>j%v z_&v8syi!$M-VH?xCMtG(&{6f$jHEE#oV!0(?PjN`>3YO)^(-qxLj#2>A;>3cjIWWqJOM9Fl z(OJ>{=he1%c){M`mtBNaarlA6j+i6fV*3I*5RZNx4%c8rkt^P~AxNke^ zgh@)?-%MV{M%MtA%^m5P3$qw|LsTrPO_4UuuhY<=+j%i4s>O(+q?7B3SjdXaUWjnK z@c@w;mZ~d1q9&hotD=bo)Oei8at#)tjekXgrzm0)o6KCy!zPRG7S$~ug8bIyY7K5G znJ5HQU2ue_0n|;1opi2F#3PzDMFt?E;|Hm&Q=+fF^bt%pFXK(tV+kH>`C+JD0=x`B zYNX3d#?`HBIne-)JDAK-{|i3L)7gIvVD%-D0qzyh`S54yb9{ zkx-u|U18HyA3wv;DF&1P_5ex&WdI?5XsDk_on47{w72x=-5OUPUmmTk(ZZ?0SL0C=WXQfU{a{i&&bbB)z2=1i(?8d00$`54yD$~!%&rQ|OF3Kz} z$xllyD%N+&PcF?(%_}L^FQ_cZnB2=4!N@!L8KW|g4_*Tj8Z}%B^<@6>0qOg^-h*#abT349K~Xw#|u5LJK{F6U0Dg#LoCR0&9pxPn<5CPH!A%rH!F-bEDZ?0nMXOt2F z3g6-=PEF5E%_}KJQKih{z$iaCg~h;+AEZ|ptkO9#Cnqr}C-oMyV_s#EJls$u94}a4>SPaxn`C2(SPEmYy>L diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-39.pyc index b2953948c92b677b0de3c5277086e3a8eebc8f0f..714e22ba5cbded797ab00a883b895e8b1592e3dc 100644 GIT binary patch delta 58 zcmX@id6ttqk(ZZ?0SL0C=WXQHU{om8&&bbB)z2=kk6} diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-39.pyc index 3cf322879e26bd43fdcbf5e8a3728657d632df4b..3201abdf1fb10ee7e8f00bef4ea6e2d573b5a077 100644 GIT binary patch delta 58 zcmcc2ahHQTk(ZZ?0SL0C=WXOxWmG8B&&bbB)z2=mSI0PVCA9{>OV delta 48 zcmcc1ahZcVk(ZZ?0SJDcFW$(l$|#njpPQPJnW*oPSd`*Ylv$RlA5fW5vN?c}ml*(E CN)E38 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-39.pyc index 13c9172734f4393d2f328f3a3c91cce3895c8d0a..e0bb76812ff79ae4930230fad851712e109813c1 100644 GIT binary patch delta 124 zcmey))yU1A$ji&c00i06^EPs8GAh*QXXNLm>Sq^a7MJ9wr4|+IyW}UA=BDPA6zdmM zmSk-9VtmEO7sXbTm|2{fQpIGY;1)I6iFq?$6iZoZQPM5evc#Oy)TqhKEVH;}f#w#m Wg9w?)D_ArbMo2>?LbBjEr5 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-39.pyc index 25b29a0b879de3e392f7b7a49d61bea0f206ae47..5730a77efb7124738d226262e4a5ad6f15827c73 100644 GIT binary patch delta 58 zcmdnUxto(ak(ZZ?0SL0C=WXOpWmG8E&&bbB)z2=J;sg;KAR>PAW;t#~#)!%L V7&4hpQI|1kawDt6<`6|jMgVx8Hh%yB delta 203 zcmccba@B=9k(ZZ?0SJDcFW$)Q$Rw7npPQPJnW*oPSd`*Ylv$RlA5fW5vN?w-Q9}3@ zYhqD)ar`az>~b(;CF8Bh52QL6BR6MCD>L!N0F7D6R0J}vC}wgXi}2<(vW$!ZAmJiT z5WxW=k~Z&^<7Q-xo_tc?kS!J@5(iQ{Sy*AIXgpW}Tq!q*l|1>Zf;EOAlO+^&8B-?< M$V+UFQ)FZW0Kh>sp#T5? diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-39.pyc index d8d97c7e2a5b3b326f0788eac7e2fda11bf6c425..98f3eb85b95b4cf47c59357a37fa4acc1c667c17 100644 GIT binary patch delta 58 zcmbQMxLlDtk(ZZ?0SL0C=WXP^$*54GpOK%Ns-InySzMBzmReM-?~;M1& delta 48 zcmZ3kI9HK7k(ZZ?0SJDcFW$&~lTj>7KQ}ccGg03ou_(o*D6=e8KcF(BWHSrXVm<(8 CUJrc$ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-39.pyc index 4c6d398870a796861644d030da1a56af97bdd4a8..99e4fbfd4d9efd773bbdedd51ebcdfcb28deb29f 100644 GIT binary patch delta 315 zcmbPhx7?09k(ZZ?0SL0C=WXQXXHqE9&&bbB)z2=F|#B-tu!w=J}*Ct6V97_fmLL)p@1-xj2+O>B6|>_2_!UGinu{+ zi0I@5q2+8)Ca-WEW7OmxVH-x9$tQ)C8ErPd6*ghkb_J={fN3vs1DU}JF#{|GG88OY zq%nCSkMQJp@zp{OAVq8tQ7e$V>tq=TJw`{cf(NWDlanM28J#9?5SCzcp1f8cIMV^yW<g` zI>uX*rwQ9I+D*PJtjuV)`Mach7kY5BMer4j>U$&>rMMJjmZjmK(8sp2Bn_p@mc=5E2*Dc7*km)iow7@JXO=s& z&2Jmj^~kioHdtaJwrqXa)e6iDD3rr0j4w=Bupc9VOMFoZ~DYwGSmTsP#Lpwbrzg%xhd z3;r|ZY_vdWD262!Eo>BCtTmDvL(1F{vj{MIfWSFV1$K1c`C3eVacy=pe z0J|Do$bXuuVX`4md>W@+Vi_5R1C0!}fbr9Cd}#@EE&HY64fH%>O~cNYwNO+y)V^AU zb7e?!@ckI!CkO^~yW&~zp&7D+zNFl`>w2P0H;>VTgYcTQj@V}OS01p~NY#*#`T2Vy@gYTgd z^JL~{(ILa}CXHQ1VLb)n9gJV4$>+h>>|@ug(PkTC7h$aB*h0!r*%fUl-Kzso?{0B^ zLeA{4Iv6laE*o~lte-X>L_qe0d@LB2poDzi_GMq)DDYm2f;%l}*>EB%mC zFB3#14_P;1?~3*88r)t{?H9`xC)I}`DQ8|u5=h(yasf8Cp$1eVq{LN&e?fY%aW5gfz#RHOho_nyZO0W|!xaxcMI&^egXM5mb$3)hT^sYN_ zX7xnV44IX)s3OZkOrg>Sshz>ZSlY_3L#%Th-s_)shMMHuu9y59HU#`V+cxtlO8SQI zIpIsf7-1D*A9Q)ET2GO=n(#5k2`1gJ=#qR_Xmly`FRf34o%&`->OB I#x)oJ1)>%E1poj5 delta 1935 zcmZvdZERCj7{~XtdtqHSX1Br0U~Fuoxol-1BfO7|vcbZP%eF*A(57qeY_V&%(+gum zm?35gvN=3M$wDIUqLARYLO?`bghbQ`20vXtDBm!ON+OB+MW6pEGD2Lk-~FHGxzBU& z`JZ!c9}N6FkQKXyE+VeUxV<0MPw zyN*-Xyy)^0#pU=Mw@l5yKymYOektW9xQplpdH^Bs7fk1poGGsryo^8>-~-g1z4D@~ zP+ppHjJC-8WqD@b)F^rTknRVzGOUc4-s|srshj7t2sSDF1YS&rknu+OxFVEH4@*EsXd&U?UI#>VN>S3Q#X5%sbP2DSZfmVfkWl z>*5i}W?-VnMEQCoR1eixHR?r7$h*bGWSJQ=x03U1M1~pdVn_~`%wGI|t%A5|qD%61 z5L31)?|S4fB{e*;($WHMy{NQ?XhcS5)zMzKNTc$~tg`e`t_j-Y${B^yR`$(P1`o9~ zu^OEk7?!+KR>oy%Y9g+%OPz#4apC+ndNw=q<<6EJu$%^ zc~5hDt*n@yF!Yc=6bTwh+uKpQ7tn!D;9cN^EOq6{#yM?;r+C;Xjxe>ClFd~MiUcRcc9cJ6lsL)(OO92==p0*9ldbxb zIES0xSI>UI>!tJNn_e5y39NuTIQNxY^s(%LSYL93MWwfTZo?-CW`y-E{)8ctA`&yi zH1tv^f;z*n+t~PA7AcfV#pGoB9sKVkaYi1f-jMSiXWGRZOwGnS-7&9{4&&KH2RW33 zVkZl%S}NJd@lU#495h4o@@W<-`|Tc&Cs{5kc&tnlaEK4jpd6d8%{YcZ`eQbJ&H*be zq(>uNmi%#klx~>MJY7izPkP7pA&)h=uC9wU*uIvREKy*(0&eS{$GLR4>c^)Jl#rmG(ksH^nvw zqLEMubCa$WBtKm@xJ2Om2`s0`25tc^Mupf0SqFRzOa}6R+dvKwl`TsO(@#R4lCdT3 zm#mynz|f6Im+tQh7{RdRd^C=CY_ujv_C zVWX_hh)5WIBP?{?lD{q~qA}@M+RNOr^eVkB8$tNA1M>55>L<*0A-H8uHt?XAt?YtDc=RG)bGGH`A+TJ0rlfFh;coz8(0a{0xN(~UHh`* diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-39.pyc index 6e2d2100950b9a4040b95f999ee4dad91139b2fe..5e894dcc51a23864a36f7f4ee3dd842436103baa 100644 GIT binary patch delta 291 zcmZn@o*>Mf$ji&c00i06^EPrbvWi79A!_-d{EYlkh`{6~R(p#mE`+jMOeIw-8H&__cKs^Q&&bbB z)z2=WgGRge-`V0}-kq z0%Q<`(3qUYuFj}6xsQFKv^G!_=g1iwmLb7E?*pN`@kRpk2Sx^m9{F zG86SZ5{pt?iZaVm^#dw1N+$ngUBzfPc?sJJ6*-`)B6$#@03sAYgbs)RX@?L7lMC3@ z8I2~-V4o;$3={=AH?brc>|7L8E*xr%mXotNG8k`7zQPeIZwNBM2t-)I%|bTSgVO^5 D8Q@c$ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-39.pyc index 361cc1856a17af98d08e5966843d0979c3196f9e..71708c332c078d18bcfc0bd97e54d4966c0f1dca 100644 GIT binary patch delta 339 zcmbOxxImCQk(ZZ?0SL0C=WXQXVrGomEXJ(Eq^bxM`c zlAm0fo0?ZrtY1)Bk})}!HBwd>s8SDzi}`>A11A?F2crNZ7ZCC=770(j%(_%MU@=}vaGV}8a^7C_w*g%b zV3T9KHTgfAoWL!Pw9K5;g8br=B9H@aP1a?fY$y&=B>^I2Kw_*eu1=xuMIs;pO^^V8 zaB6aCQD#YHcw$jrW?uTO$sgIp{BMbS<`sh^QUh`lOVaX-a$(Yf!G4~;nZ?CGr7$6G VkC2c6CKt7X5fwYu~?_ymJY!(%}t zDR?2Qy3t8RL>>l)c1aq(49$}n2nQ-81CIi)97S|qg{j~ZG7cYtG&02uQV(^ppJl%% zt2%XJ2nXJjPMF1`zldWQ<-EBRdPrEo&%;t^mRZWKwz64KwGD-q`?|_Tg;ywJ8ZfBF`t+YpP0G=tUKGL()kIsZ17X+x)H(Yu6*A!ecK3cy~Z*Ze7-AYpz# zev<3VE7^JGpU4#qFTp~1+j|*BFX9TKz+ag}cBC4r83dmJe<&>Zuh9R#Fdzsd3!fsI zgBQy}KKfmlJ`l=JS7HVpT7}ivu5XU1)X%U;FQAC?IYJ6>F^ycv ze1{+H1K%46ZDndqH?+*W#`OX>c35U{x7u*N!M*~nv(x^#4RYx5KZ7hj_wPkBVk;jd zj1k5OIYQo<=`4C7gHO93_~%5%^=w*3onOG&WEY+aYA}mWf^itdSHX2333!|^j}M2t z@nq;V;UJ Ws+P{T@m;D9&g1vgPiUf>Ui$;3Rm9f- diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-39.pyc index 39077ff07f26735c9716f4ad07b25e8b982a4168..ae87796748526d0292db0c982a3e12e3af541124 100644 GIT binary patch delta 55 zcmcb|_=1r;k(ZZ?0SL0C=S}1eQYhEY$j?pH&o0U=F3C?zEh^S`$xklLP0cGQ)-R|m J$(UH24FJgA5}5!1 delta 45 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 delta 2665 zcmai$Yitx%6vvsqw%zRt#g?KJDJbAlaSbBIN0djmErMH0Ula@DboaJ9FgvrHnJsON zX_3T)FCyF+O;p4v@sSu~Mx#aziZOohgMPus^&Rzt#u!a}#BZMeowgWaVn6(P=bp#C z_ndRj-ACRr9(cz{Sjl930ssB|q5o2%F}B1{7e(H-(p?ti+sPgm>0OhBAiO>Hml0Pn zF_AOJEk}i$>$Vs*TiK3oldX3*ho|EG2}8->n+~t-4z0YuMC&T#BTVj91{Wc%AS^VdW63z2V4i-262qV zRuB*s_$yUO8zI5AXiT0+UmBikc@yrYSKM+v+|dAV5LnJoRUKu=AvjjC!xp)=J9fc2 zjl#vr*7poOke{_4m>mtS{2`HrleIv1*tu%jFtYOfD_0s*;g46E)h*Ky%m7CiSykmD zoCYQ)Wj-}^;~oqr7%J%p76m2;$Q8MO1O)m70Y>)#G2lLil1=Nb-Y|txb!ON0T^UuE z>Fw(8YwsS+s(5DC?(V+sz9F8jC(f1`*hS%$11d^y-3sHVJie|}6Gc&0w{5uP5d0)f zYsB}Qav;nyIjLk6!ZCx7X5QIuv?>p6K7)kjK~+pT%1Bj3bzL>$v* zJ+1ek>un7-Qaegs(X`!ww4pxrb1+#9JPWiyFD_iaOv3c}dZaKr1FQmYuW2VkRpq?W zq^c>G@>U?I5A#<6C{1z!u^L4BsR)#Trx_}-dp70U9AC*#JC+*{%Rf6--mL0uH%Fq# z(N&fHq)+!lyV`ezC`Gv>_|TQ8YcR%@=aq!3WKU=F^dk^9!K8sK+ZU$ia&hHt;_IQ} zd7g9iZBYxgM|0F8mIpMcn}g!KaRaO4#t^k4Rcrf^TrHgU$9FC$`>Ewoi9CiCXMh(L zESO#pB|XXtCSL<|04`1s3shn*o94m8Dqgb47kOMIwK&h!V!KwrrD6KH0tbZjy=veJ z6c!&WDDc)$KdMpRnV`%)KsdbHLuEd0p3p{AJjdFuDJJZIp1?!{Te;%!h0f~IlbBD= z?*u;SRi2~M+F&kxCUZ3pT3*O zfs(DgS2T@6FdHczZNg_c?Co{&ik|Bmp4L&)hnPQ8s(}Wfr*GJW7gMjHb6N-K<$zvI z$5`O=Kb+AJ1m7~aGj8O6Dq-b~n^yGtHc1`MzmJzVx93d2-KyXotZ?wOWrkeXfft6q}Cv zm9AB+$nRa`J0~1x&c6=t&rsGYotJkGZ86S2b$qDO_*gzTykxQNv3l2Cti>&^~;aU##@no wRpX5u!0(E2=&aW>nJt}Lwr5o$GuYj~vwiE%?rl5hUWjox(#QObe;ZEx1K||sb^rhX diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-39.pyc index 750c13b6127e56967b15623de62c98c9c447b6c0..753385ea25441c39a0afac0dbdca6a01fff3edb3 100644 GIT binary patch delta 589 zcmZpVo*2!Y$ji&c00i06^EPtlGb>c;XXNLm>Sq^a7MJ9wr4|+IyW}UA=BDPA6zdmM zmSk+6z+5jT5XI~6>gO8d=^XDG6yzTiHCbNjl&~exn4Lge%mO4h7+IK#EGG+!m`pa1 zE)}){3hhUcvjWS#kxpi{28th@{7%Yg@-&%vRvRGi^yF32PLpk9>sW1pyo-}VWLzdQ z%cZf}0eROa|B`W7l>i@u@>2b&FqxVW_19HKbxE<=QP<`VK1vAkoRV? zyS&om2g>G~!xXPEvN-{Tikv6UR~4V^sT{!QvU!%WAftdANK^nw++rz7&B=+Hyjw+^ z%>yLpIr)vsS~gD*(+Q|cg3)F24pk#Y*U9shB}75m*cpK?VFNNiKIdUCas#`?M=e;` z3n(Z7l7)wh*W^Yv5ujT*C!be4!WcDqiu!a$@5wqE#lqe|wQ@*mS&F>D<~-9V6!rni z86n9r75N~UqcM5C=6Ocn$@N+iKoe(ZWwZJM)muznqNX%iKw5FKw|2I008qpM#e{&# zC$(*W>e+NQv4P^R$ZGNy9d#{mIDp)Ji_fvRIJKxGGe6I@s3^av2;{&bkV}d{#uo)l Mz9=O=Sxq+)0J-dulmGw# delta 629 zcmbOj-5$-I$ji&c00ckJ7jNXwXBNxX&rMCqOw{*CEJ|@H$}CIO52(y2**uH6UQFN? zue+oobBbTX?gkau+Q zNm-Z4i)3P1?SQ<~lPlz$CcDYj3EKmC7lF8#1xRo(vM?3dPrfK(GMQU0L)ZZ*bR9*` z0W7ymZW5~_Q2g#>c15Mh1;UDxr^sgsI{`(Wp{RD6EU55N*cmAH21%T?$Qfvg$m9!Z zoRdE*>upX@yvE4p0#s1sI@v}!oy`rzRGK_dLt^qlrHH z=YS#?I{C7;4bW)5)ILjXbRk8Ct`-Hx>B{&IHK1YVvx{8`jYU009suQ~Gi zoi-^;2A!41CsLgG73S)mgK|yW2#EIx;UHJ?tk6L&33C1(sZ(EmDrv0)c`B9$K~`q+ zOrFVB{f)%pPfR;R7wWD~WY!oW4lB>^}}AvSmf-w)SK) zBTdsn@}trwlvKEK=!X$gP+*xp%E}nzhTygsLjVO1 ztgm{lvbk}odZWC(vAkN|EN@kA@;S$#K$wc=(UA1Lo|ooZU-fUYq|?tmYiC5+64WLD zmH}1)I#jLY-e<8Hk%v@PV%?VK5`ITjvd5Pa7sIhQ34I%}n2lVl(S!cUIbkol3Gov2 zUE^Tr7(EVAK&rlpP3Ir4(!eKaOxVP52?R$Tq?H@|ElrD^tneZhZxG}JOfh{Qxi!26 z!pj`^;-HB^?+#}Mj_&ko*pnW@xmj!%5xfJ^ZGa9vi`xws1uPYKm{gl+FEEmaA=B!} ztRY-=O$Qm>?Vpa98Lhr`f21N8Z$abhVAejESj=r;;l*t6U5YCJZ(IRb1SoRIcHt8J zF*25iqVNyBqHmk5$|nor~MJcMNqOtWk=2pmM}UJY*oEtVua?g;_F-&>ES z25y0VNl!=%RL`8trh!lZW;w8=Z(2=r7X{JF)F3eqaFv>wJ{8_4h7k<5U!P^sFn~sNkAaGJ#L3Cld99y6Z+&|15Khr;J5I;77)qBN*JgH53n%8~cVtKyx~`>u z!VsTMy=~gGx7DYxs;CPcs4!?`laLm5P{M{!spHZA#XUEQ#c#`6=;ZI(PHUrlyY2WO zt{H|ABNC!DB#cq;p$|i9eI*>3d^~+hD>ojdjYO}7k*q|~fEzGg%ZM4ouByhhj>m~JDvzn6CNg&5GwQQt zwjsBlRLc-aRu4TY5+3y-!?!yJMwPu%Q^m^Ws#Fjb&_{I|vE`5esqOJv$iCNll}!R> zaUuI|q;VnlOM9SpKaGM(m(f}z3=)Raci;vVo|ljBn_?41HKvv|5 z?eFojJJ60|M?|7Z87!gbEksk9_vW)BA{7O|me=TpFn3&hQloz?*NIo(b0-?r{F46U zE(+a5@trNI7Tv?>eTfCxRdpEX1$Pja5R($cmUvS~ny28nQ5Zxna|0h#f7_cGFR+OU z?>bJDxz5LWU}ge`a}vU|JrYGV%2oph7BQ?^sC-vc0phPne4Q{>;a_`BY89R<49ylW zfd3ARN{CcQ>@`xQQG7!)nCM50W7epL4q;Rzf%sJlWlZ3L1bW7Oo8%+ZW8n^{>rnOtRo+KYrhgdCg&<_d$jN5J=o&Ny<;DERqKC)hDmz jOl8!YEX-xfC^^}a%UDzmBrF0VWI%)ph|rrnk;@4H{3|dd delta 214 zcmcaBdRde^k(ZZ?0SJDcFW$)gj8QCCKQ}ccGg03ou_(o*D6=e8KcF(BWV0aCLPo}0 zlQ%O*Gsy8!mKSA~q!zJ**lZB?t;q?Tj$%?EU4kHCmZbcY$|4yMUvu(y&QwN&$+BFgK(m6m Xj78N!!Xh97WL%Ldh%lHuo689R#LzN` diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-39.pyc index b98a03aa8941a8632c2854eddb996efcca3cb438..58df9415c860e8841e4732d5591bb11129ce7947 100644 GIT binary patch delta 2503 zcmZuz-ES0C6ldD)c0XDvg#s3|rLDkJLZPsATZ5s}f_!9KX!+=%Frr z#b~3LXw}4+c{RjWjKPq7@gMNP#KibU=0SZ^_RCjI5yd(Y?Zo_l7$ zTmEr5ZFP62w#mQJz6X!f&$X`^sS;Z?ge^<>T%ylW6yWW%&SEU&V24L z5m`#v_KhU8Zn>UaGJ46OSK~G_t$dy{A&f5U;lJRx%;;&Xs@9qiD<01q-Pp1j_mxI- z$=O?xxowexFt$Ti2-jR@TsU4uZA8ar-r-FR+pGBOZj^V~x+|P}OjT55R$iJ%^_x}h z-Cb3wE7^<`j2(y;?MZh9=XRq)yTp9ctNJnp5t#}}fY{jE2~$f5lm%8RmgIPM%Vxnz zRcfgk!#WW*`CkG`SO6DXkCv}NmCU?JZQr_9qdt*hf%*IOG5x!TD>5t8L zcCE}Rz8I^n`o-X<fNx#?VGQD@DD7 z&tRLPAs>De3SA2em&}W^OV{VF%q-{$6=uVp&q48+1S5frO+r{P?S1{dYGo9N-Gw>Ehx>_Fm-M3*V-`jBz>qsQg8_NvjFnkC8cn0@Ob~;UU^6n zph&qG!P934d$y!~wLaSak7jKl=!Ue>V;mKSF}y?N{R*}_m0JUD;Tu=txfFq}NL8~X z%u@aS{(RecB7$OFgR2hS3oq9Jn~9LYk$l)*<1UA8sMR)6actmc?MCzJb*LmRvejA6 zJsy=FCOrA5xs#Ve;+7>C^{5$KLgk)(Z!&DWdf@l}D;-al!H?(rGEJ z{>#vkrcDNuBb8|zrc_%ul4+k`8s~ZJ4FJ*-B4+!Bt@xSSk9 zwa?Muk$&1DzT;))7ri`x6S{W*mjO2=gfTg=D!dGF2WN6JGTS$0b6A*J+=U(jhjBIR zT1&&37tD=TyQid>)3u!5p5xizhtX576K_P+G}O)masYIjdT&(TRV0>>QyBDC3!)S)RHbOP|o z!i33L)wSdo#tt5wI9MLU2}%e%M6D`YZWlICj-FEelcY}qwa+=6(G7hBX&pc_Oni~2W*sQ2F%mZK zl0E+v)`~Vr*Xw681DgC?*b_%|w1#R4K8Msy9yi$-GVkE%e|k|FZb=!2skUv~g45Z<7WG*!cb5809#GF|i+Ym3 z2cPc)?gKsm;HuOZqGaGH?2g#Cnd>%gfU2ahnc(~E&EZd^qPzf*E+01~O7DgA6eYoh z$-jHURLytXqj${)>F7rdbMqoh;rpKVYgL!==W)7g)6WL^ m%LZzE5Y`hC!cIA&e8+Ot*I)+wI{`?J_W_z&MXCKYHUA$l)?_dM delta 2500 zcmZ8jT}&KR6lP#q_NOZpO0l$tQZO>ri1sfnwvD!h)>bGf6iWRWraKoHncdmmnO&fX zZj73$sW#1xZyHVfNm{F>PE48@6Jw%JCN(kf;riAWqrUm#&x_vg+<^s1_;T*~Kj)r% zX75zKt7Pq5E>oxe{<#y}%HG#dm6>_AWCi&-R$wv(dd?3*O_h8e$}D)HTVQ@UK5!Ot zmj$tIvp0Z92PEDRZ zb8O5^=`btyya2^vD5grj?^$^-;HPn{pI^|4tmG`yR*@}ON-g@mZL85`!*mWX16b7n z5{TaR9mYg-ynSzdJM!ZQ`r9Zd3VKjn>*!4m;e1ql)zS4RH2_6vIn-sAlA2$z`D{RG zt_~Ar@4abkfu3p~YEUgW3i~`@Nc_0v{$_Ft8HJZ3(Yd{4U8Z5Qr}J;aUe}Wa_)BmU zDHC{JoKn3Ac9ZVnCAg*Dsax-#vHS$(?sQ}j2u7V?Z z*-+*lhpsfrtE&g6OBwcOA6^F4zIX zHF{RuSi11WitUxzx(GaoO5GDi9}+g}wWmzU<^gjo5iIvb{oc|INDo$ z;uT~?)#i{@!|2p5{wjC}09geqUX{Ce8?N>m{n`6^LsByiZ)&iM|10lHTJCBTacWI}DGBEKrO@9fy|7Ptr_lX{1(E(Ee`Vrpk8cTSNbrZHkR zjPMEZ^Ugz0Q(%KZ$#UP`5y8-GG01eJGDC!#OxNfM` zq&AmY_?D$RFa`y9{XtDi(5HyHY{sZJ#PFU0V?w;P$9-l}@l+$|6*lpk>ZEg_PLuCi z#WeoADR%l3tB~_`6Z;a*+m+C@|dBW>$A}UCJ=b)YsLCll%K@n$VGv zA(~JnplLP6%{2c2o<0P81o#+$HtPjO$-t8uCVd}y=6TC^LRC`OG4a#>=XyR>is}L| z0BQ+PqV%pvPq##jANZ^Fe5M?_-otq4OMIi!J};gf=xL@@-c?6lR3OFGfi08!L2X(y p$m(Ye^PGUw;EhAxr1n?n+MfPQ&^NOUZfFwQLDe#d)A(;-^nZj_jp6_R diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-39.pyc index dc7576ccfc4a5cc64a8af7c97217e9332cda90b1..33dc5f55dd5b958e0d17fc2e3b336829e2f36c71 100644 GIT binary patch delta 224 zcmZqD>Cxd%Mv>NwI!GWl6^7a@L>Bj8T&dIZGKOHb3Xw z%%~{=G`@%%M92b(TO6qsB}Iwx+2uvNATcn(2VzNYKFl4-!Kg4U#G(|JqRg^X{ea4hlFf~*KbaYCO|IrFWt80fk#jR6w5X5E#srBm`az;!^!cB18OA03_33jx?{l7W z-u*hs?oTp%C?_X-8vX5ZzW0g!gt2_6I;Qq3)w_6aDy>Epo~mw8!-M@wBAu#E4yR+< z72`|;3uxb&J3~FCB%7Xn6E&9j9Mx_$|_^eiLbIeEFkV@McG1;w9F`~ zA&(~dWQsAH$!6p=RIF4xm%V}6*C9bEP$xz=I}G$yFx^u$Wy!G3$v9BHf?5*$=#w%L zD4Uhn%50~mZ#P&1=6*Gzyg92#v3ZKKse!x-}S#sNrDnVU=B$ zQb#?7?nV_GsxXtyW~6o3i}AdmYa^+2Q_ritN!`%R-DVDFj_2fSfm%_PU(UQ@eZG^} zWi8Z_`F)nWW`tQIN;FP=_45|(7sn_wwUSnx_Y{f!GplS3^uul7K5=2@i)^FFD(R$F z_LLl5vkI~1U{Y1%x;+?H6A2}p?o|_9wr>Zl+2Pn=VplM(MAN#lM@j4ExH_b8-YAwj zE2`R%xsaE^)6}g-hIt2xyc5_71c5Fw;w++)$DM9_FBBo5TikNGSXjH~{E@Lval6!E zk-;i$*bHHseZmrlTfa6jdk4HqS8dAu-_UU{Qo>KfCG~ zi%GF=?lD7&kNkDx%b_?gN2G)c(gyL{yfxI2g_TizrZluW#8{<+HHu4>W%Ca~fv2JE zz(ev^2)ZS%Bzn@ZfHm`-;+TYdi4V1v)w z+~C{x0`>w1rtsPH{ltpCobRiDyp|-)5#Shr)5RNsBLufG)A&5vxHKKnpppoyk={fP z->q$R`ISqaiAOEKn@TC&>DUUz_hrn4^|xNPiKA z@a^?~I5&|aHCyiE)JbOD0qy&`!^|R!<1|z8Gh(0jR^4)hWbp(_$n||jl5XQlC=%~Y zD4A1n2-c&3?7&kbJ(yVjft;)H1{ZTLf!Zju=-I(kD5?aJM&_QnwE^v}ugNqbClK?J zG7xgI-T7QjCZ>Zw4V(e+9?gs=#+w%dauttO%dbHvpWp^0Iin{beNLcxD}(%K0{M0N zsavx$2QxxXfJ^4AcDw0yW(mRdhzM>jXMNPBzgfH3y=7+37f58{=U{CV6I)#Dy122W zgSCosf7QtQr1ra+-)->w-HZ5>?t+vr&H-KnMuB|<-InBPQsL=g?tyLy zkfU`F(f}a)a|MzUFad8*8zDY^W+RjnfE)uXS+|Gdp;W40NypR({}8s1feU~J$cAEA z`DH*3+*L@Q0&*W@lVyL;LU$AR8YmZomIAg-v^O6n{?P1T7sX%Ai}UuvXa>fBwPIyU z1sf7OTLMfMS6eEU$v(Y7Hr=9j_t6`YJK!k)J*k0I3)BN%K%S^=^k0fYEZFM(7uUf; AdjJ3c delta 2396 zcmY+Fe{54#6vw%3*LE$H4H)ZIM_btjkAVY$0bzrUt{~g!1{-cNW_fF0w?fyJ(+(Jf zUqMBT36ZM-)Jb51fnkWgU=&0YA_*}>;;)1kV@ya){6kGdV)(d)#|%_Syg z=s)FEG3V1FovML3e4;H-G*_4bab>Imc9Vr!7|rFIZ0D_r&^+C1A7W(-g{`=Z{NACg zrV^<`v=~vDvVdR6_p)s_;low8?QVGKuj---FEs~9=k|ev=&HbJy zSu$v(rJ(X!OcuT*+#4{jOPFHmncNx@BT1o~(8+ei8lx01u9l z7fGZt8l~Yl0PGh~%sJUOA_+}RhPCbSEFD96{oCrwJoRnl;T*YPR=_$1Kyow!Xuu%g z0yYDOf#U##pxAPInAHKHH+WwL-W4$T^9#JJOCMUWz+AKexh8raL8OHgD|Pd0i>ixr zN<#Sm@#b>${Kdbqh0rxI1Z}hxw(R3ZSdWXJwj;?&QtU5qWyx&km@KX?ndXyA<%41& zEtAg8*oRVb(C7JkOSZ8v6wBw;MyPF_v-Xlq|Qw+HmflC0qcs=!LS@C+3H5%YQAd0)$Y5nJ=MQk$MhHX`AkSImDm%(Kj zzs!C0`^y3k3awBqV@k-;J$T#RuK&vu5_zKAa*&wU10}FtL;tnm0JF-S@u0fdS^iq! zM#Cax<!GP3sA85{cDV3TE!6b;4I((q&y*bngYmEJUlI3hfm(Y z*RYNQ!@ySpLT~b*4;4r^gx9c@<(|GMokOPYA*3co_1jIaGOK)f9_H~DA6NZuexl{h zbm;jm6L63lYhaQUxG5l}^8xH;KDye^Zt$C{H;6C7%+T~bXM{VXu#jR3g_PO!_}7cp zV9`;a9@q=WPvt&X`+=7P411bVX^pZ&R0ZD-KuYfwSXn^!@N-xmzyiE8Zja!jzL?>Z zJ(Wtqkqu`gp=L4zTDCtGrSnMm82AME6p&4anCUVQ0ImR60XZu<2swjM_-+9|0zSUn zHi@m{k=6qx>x4t8777W+2D5{tiH8CLpo`qxHm5+o-}3PL1W?ZdZRKnS?{8br*7Iv^ lc#Dxck(ZZ?0SL0C=S}3cQK;9?$j?pH&o0U=F3C?zEh^S`$xklLP0cGQ)-R|m J$(R^h3;@8q5@7%U delta 45 zcmcb`c!7~Sk(ZZ?0SJDcFP_M4BUY-Po0^iDsPBF>10hb1);<lkHfHC+}lcVdDUrQp7p=1#_1?H;BmtB&vkm^Yhbl zQWYEv3KU%P(lhf?^^15XPh?rFB>V?lv}YhHS0UaEc(-{jdW ni?sxS(wgkI*yH0<@{{A^i@@61KpMG01QUp01`&djGg!?4?$ji&c00i06^EPrH;8dv5&&bbB)z2=lAm0fo0?ZrtY1)B Jk}>gA1pv$e6DI%w delta 45 zcmX@Zbcl&Nk(ZZ?0SJDcFP_M~QmjlrH#H?QQQsr6D8;2Hvn*9VpfaOm;*|;jKI#v* diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-39.pyc index d26cced37098e1dda3f3cd81c6192f463de9f6e6..ee48bea3d46c44ad8b02a72082ccaf3966be6958 100644 GIT binary patch delta 2757 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 delta 84 zcmbOs-6zeR$ji&c00ckJ7jNX|WELyY&rMCqOw{*CEJ|@H$}CIO52(y2*=)l6jf3&l lWNn@RM$5@HJkE?ZlMnDHFh)&&$fE)jXXAAPium$+0{}2U8Ib@0 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-39.pyc index bb751cacd02626b0f0166ddfba2f5bcd2a4ba2bc..3eebcd4dc2228c2c012162c8d0cb86284fbcd378 100644 GIT binary patch delta 173 zcmX@bb%l#Nk(ZZ?0SL0C=WXQnW|EDPC@oHnPs=YVPb^Bw%u5F`<18pa2|Eko_$j?pH&o0U=F3C?zEh^S`$xklLP0cGQ)-R|m$(X#CX)Ytr;%H_@UVfl@ tO|~LlAXUUSIfKQF8)QNenBbnglEs-(bn;skRVf~js3=?tS&?QJ}tkfJh3PxGcO&)jL#@3DJa%tzBRd+ zNne@=sQOpFer{??W}?0aP?bwjW?8C!KxIbBcx&=O<^lj)KotW3 delta 54 zcmdnZv5|v2k(ZZ?0SJDcFW$&)!zh-opPQPJnW*oPSd`*Ylv$RlA5fW5vN@eGnTauK I@@eJ*0JUim9RL6T diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-39.pyc index 948995a1ff5a5dbf62d8c6f5d0f2676746ebad6f..6b3b916c6d9dd89462aad3299e2b44ed6eaa699e 100644 GIT binary patch delta 340 zcmZpb?w96H+s94`6Ke;p)XhgAoL1jtCl#ZFsa9B_?O^G_VQ+1)?UuTEHMJlCfu`0BeF;Qvd(} diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-39.pyc index c0c1d959b2894155f60f322538f5e9035fe23035..e0a222c3dbf2b1665655217d2b13ff4a342c5bbb 100644 GIT binary patch delta 64 zcmdlcbU=tZk(ZZ?0SL0C=WXOpVN$5k&&bbB)z2=gv`vURk(ZZ?0SJDcFW$(V!X#FtpPQPJnW*oPSd`*Ylv$RlA5fW5vbmorkc}~F I@8Dkn$*kAVjL@npoHE6js~rI=hQ$Fk*}+ z6E!-<=s`Ui4Tl^dfl7*IJA$8hIKy&veT+vXohoQA2a`v|w8ivuH26OTLdy-HLy7Y-%hurUYhY zQxh{s=9G%m(ZtAD*rz`vWo7y^;H!Y*-q`xwHyjfYSU(U427x+Y07w8sz%VcZi~>nu z9GGxdT1Uvr-~9~1@^>yK*8CiXB;)NBQn=Aum(eww{iom1uep^R^ZB-x5S)5`$IPfU z_14)%lZJh4(!Ji+K*%6}yo1)DYA=wXS=Gteid)y7A|%QeI!^Y>I+3{N%j*R%IGh+c zJd;eOrxPdOL|iB#%_vw@b8LNyrYU0vv(hp?oSly6wH|Nv*UC!ng`3x`Vr$$&j2NhL=o*1MCQHHUUk*W?*f`UWH?tl>NwK zBQ6u}gUG@1+RKoK06F?`{$Xz`ndDXbK1Kh&3unX|&!5$EqP^^_IIMMG_x>+Fa+e1RvQ^u$(wgBEZ25J16`JaZtmNlfkJpH(xKH{t(twQ< z4Y&?9(hd_g$+yLx`AbvctFcCs;O}F*L~rZ+Z>$`G;TB*8Xa_W)510Z_g%{Lvs%7P= zy=Y|EDX8VznULgOt}U6|LiSTrU~(0Zowy0<7I061Z;x*wcX=#+r$HA-FOV}9#QrU? kEG+W;O}yA7+lGF6e&g&pD*hZ~ZnONtKnqFnTLZ_x1Kvk5WB>pF delta 1291 zcma)+%TH556viD&TLg=QXAx=)?~6PPN+3K0kpdzVqBTe~sn>RZN}<=ewT_LVFI~-fLj+Px*pxQaASgor90;vLPLn4UHo$9%$##(zH@GW&3&KC(mkHc z1M>I#lewOC$x#?@oS~7Z-Z-GMNH2@tqK%`;Da*d&*zo2GSFeA_AM^|N$Y}7~NZ_L2 zi={gsRegk<;zQLVB*0gyi}OSdqZUhs zP$Og|j2IRCL-j^cQU3&bZ=^{nzK8>NvA30&%}ZP5Ff8W7rovHJ3;aagS2E5$^~XrSZm7>BIpgqW z0SAG5_CP}k=~nVX`M#j$W*4wi1bBgBAk`q@Oc(}b+tm+a({I0N>`E(Gf~}gZ`iAQY zFV{=F=~_Aq@VusE9b!s{9C+vXSgWt| zFAo)mOiQ;CW+)s_%v$Ob6V9-nkhfCbTpprPQP}IPVUmxrkpeu28`su|6tSl5U1_RY zTE^}+`T1tsaXFQ~_T|MP1Ren%0u{g%&;g7Bc$LTs$8^)2q1IG9!mhzR4Pbbgn$pzB zshMOuM8c6}Kq<2V>lN@;qC|K?A(c8zW3fT&ONw@#{CJ{2x#^4)VE9AGyrmyNdW)XV)K%!6eWC diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-39.pyc index 885949837f043b1f998758cfa45e27a2543050e3..f01c359ef17db2206371850f884b06a42694d97c 100644 GIT binary patch delta 1199 zcmYk5&uddz6vw?aiD_PAtJQX}sjZr}Nvmf3F;)ws*5p+S#iU89@q&glefeRM_v(Ew z)aXJT7&k72IkTEU1$Cq7LY@nkZUu26I1B;*0hglSM(}=b7B!Gh&OPUQ&O7g(lXtoQ zb6O!73~Z2}+R*(MTCaEXYOG>4j95)nZO1AZ!j2`ZVzXhGjvZTVITiZVdzW$dwf8^f z*(>wtW?+Z=a??pRcvzmqZxYdsVj6bGL0b3c;6a>w5c7y>3IrbX9+QVBOdNr)OH8}3 z0-u`vN2dfpQ~rJ{khf2|v}df8JnVO zz3*qZR+1eXVpUX4hX+@xWy5yzb;B$>74EMT>`JL=7WtN+RQctWW7wQ-_hr~Qx80ZR z(zrLSr?dH}SB%oJ{+%pFx&B3Vk)HP7j_~eOI+;zzlM9H4(eim92V4MR0H@rxS$4_& zXWL)C&HJTiPTsc)@28oe2MLup4kg}8y?VPhq0h}OEoAfY`P3Obo#|8>MLYsTfeBy| zI7GvtK~2?M#`yr92<=FuV3s7JK5+{6EN}?Gbc7+ngSK6-8LhfiE>-JBXD&rVF`V`Q z-5eSqH3&%z;}8sjRx3r~;iMv<-a znS4f%FQxTtdiHE4l}u+v0&<HWyw&9cJ*prfuYHvzo71 zwqq6=2KU>BxdIob4`bKaEq8Hzk+JjiXhPqCg?$#Gmt#OOKM0c?k4NUIa z$~~1vp(yImR)GX9O`12$^s|}Fg18D@6G#FhfEs8PmRh7ySm>y& z%{Nvp;pjqGg7?S?I-+3OaCO#j3`(_9YDYRNL%&b?kG4IRt*R+1sN%DhFB?TioP+uz Ua0yUDy#)*RCmf(fe@wmo0c+3~3jhEB delta 1228 zcmYk5&uKKdcq z`<70EQyRHGm`1xN$lLiLnH_j;okT5({(hL2!|}VR8U5!zfhp8NFdh6Fe@PNpp_h76 z{*ug*Dfwq|r1*-8{u78v#3;g42%A+^g!{D(DpZP7*rH%JeJ+^Orcjh;tPwIQSFP6W zw=wH9;$6g9#Hf5`?b|=0&FlKhu?aB}OT_x)1F=4s2nGi`guEfIrT&;viMq!c6gI(Q zLRqfYpj_B3${M1nVoirP>m628J70;i*SdmoC2ysxWHoq^UI~q>@N8*$#mwYK zo#9DR5AF?r6B#UMbxwELgcM|P}>`hTd$KtEBEV_k3o1tnT+#S;q*xDHYW%!IP+v&sCJNEf0Kl8kR7CY2+d> zi}pDL)-*Q?ZEY!w^VSCKw){rjYf(6W-VJ%@HJ4ltLI=JLlQY40qc2HiUORF_a2fr0 zsVcfqE&=$ukL9W{%tC?wBxwro**~!d}wXis$D&67K=FIzV1XYYv=AxwJ^USB@X7It$B|$yA3Hr_J3?)e{6eA}>a7F%;y|eQZ z?bYvUO#c7|DETmVG>?x%t6!pe4e=Gi?AP?s;2>&O<=?r(Hp2-H79 zl%ze*Tr(tQfg@T}$%U$2dB0pKy;rR+!WS6#8KQzXgt&w_k1!)?h6s105)183A4KnV zlKOrHIEWL0R;&&bbB)z2=Sq^a7MJ9wr4|+IyW}UA=BDPA6zdmM MmSk+6$d@ew01tQ*kN^Mx delta 48 zcmZp3`{T-;$ji&c00ckJ7jNV);1es<&rMCqOw{*CEJ|@H$}CIO52(y2**u#sTLb`i CT@WAu diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-39.pyc index 33d983635a6c7c9fd5e446fa2a56765deeb0ad8b..7c110ad584fd0ce2d0b3c81e4ef09502ba8b6e46 100644 GIT binary patch delta 1743 zcmZuxOKcle6y?QsmK9<_Hs#(i2{yuu<9qMB_q_Xi z^HuKqoLBDbY<~oPJA)s8={<4~TKmx9Y?<C#(2#+J!af|5EDM^Kr zY#0TlRFb5Iyr$64t~|u=_~uEd_M`9JmP@l>{+$3oeyy9TR*X0;Vo+yMDXC?Hy2`31 zsl`3&LBTd!q-Z(7)W99!pZe!WqV|)&M#h>8v)mU;a(SaDFa3%M1OW~v_`|+l{!Ooc zQ~=fLG^&j0Te7KCAn`vinJ`0SOZ-9a^`1*0M%t;TpqDGU27{*jurE-gk3uU7ph}8X z(2J_JWl#?cNZQyp6@&JuhScPsK!ok76s1!ti>R~}1E?EO(pj;ouH(Kmp*-1tw+A=F zBGH4EXtbW(EN=~jNtjOsmYUYc2na-}-3xRRvc!KFNM6K-KzBQ!kD6RhR)Ov6L&CO_ zyrGmDuLLU_up_Wtd^H#$&+*;hI$7rTgTu}+o>TrH*q0qg0#|bF%7T;?nT!X|W1x%S z3u0~n>Vht)m1~P^88oZSFlA<14n-?c*8%hrQfj=LKRdWWcKK(6e@l&ag>+nm;j&1J)vC#5h3)+hm&$)0I#1O1 zhQAoKU!K$Q`C3REzi@I3 zl+X|IT|&Kz279JRn^mn)FDAgh4kcznaBO*Ui4}2G#QR=E-MOAko?OmuA{o}hG=4rj z0<~Ta5Bqk}pdh@8@EYF_UwHZu#T@|4V=8;5WbVTXrqEahh;-Qxm9`st6*gC@vQm9Y z9=U36>r91*efrH|T@XR}!|=544J5Gp|2j$m{>1o8ZO^qC?)YQPrKlbMJX-_S!(MYS#eoP$6-cD{tA#Y6K}x%U&K-A z{G-XC8x^#5Nh_ILURuj!0l@ohFv7=IflBeXJGcInB#5cxs+3rXXLIZwu>Lbel#UQ^ fEm#79BG`krN3NoJ3&HL^w)EdVyG}Oi$;iRqPcN;G delta 1843 zcmZuxO>7%Q6z;^an})<`law}2WZJ}P(k87`D%^NmTewcJodP*9+ITniqV=xz zcJ1b;X{ZqG0jW|MR7w$qYiL12K5;GL0tX~GR2uPf;Dk7E;y}4DZ`_n5!iUdq-hA`T z`yiQnJfJ70!wdkAmb_xM_l9271?~S8O7KTx*1=^9<(X_|KANSP2kYP0;!hQ=r>>5MXvw$Je*bH6w96pNP z=Mhls2{{%c+~c?q3&1!#8$Qvs;{>v%SS_sfOrg0~ko^%ZXJTT9`>SA!T-+6iBk?4{ z1cE$w1}Pns7ERT0in?i1x+AXR$dj2z*=E-yi8g-hy3=xTQn-I70z`bRONOPze4IGk zr|G6qad=zBu&ALe^8gys$%)22!nH#?!anPsAgRXB-3>ChJ2CD*XR4J&O+EiB25^Xd z(KANU?5CbV@)G-}XKmwUygSGPMY~e9E!}c?hiYQyG+HdH;Bdcg6>ZJ1N_@Y_y(k!T z+vD(n=m=e0adn3uFdVvzplf`;WTMnFbz<;VJiz^kG;D*mE0fmVEGe;k@74jF1y06S zTgJx$D+H6QvoA_U*r~qry9Q^yFG-;Bs4q-JPCrD_=dc8#p6#M?mfDO~7xUDMf?iWy z)Xkk&qIADJAq(_se~gsbjsAI(VUPOwmQB?3aP#q|SnapC6IW(Z>UYMDCJOz)WQ-z7p8AssknVc<|(|hI9|b z$lb<^L%m*~e20^4VOSZN-o8fU&?oFI!b7^{)Ig_8HLKXnCc?fMo*9dZZ63(aq?F4F z-gh0>zWH2w`*L^>#V{dQW2d7-@e(pR=S6qY*^9Hy_K0U5|$W2{7`UG-P1YlFX=8V+m8D{w9jc3qiqLM}0*WR!fK?l>=Y*KxO#re^a6IyajW zupwkVMz6=wU3d$vaDM&*O)8o6<)_c_6XAW@V6;9(z)^w}0***?2IMr&NKgqx1Vj@tJ=DqCB%tv;VwVUa*6;sF0Kfl;-P`q|JVIUnJyHPJ} zON^X)*t!hlc`tG<`n}HZ6Mg}_;b`IjRy~2Oj%@j!xYCN#s*?&)Hc$I1{8!pZ9zuy8 zl6R1!DRB%QwM7H+^e%GyW%XlhqC8XcB;um7IIFNGu)y^aqsW+17$<^e8 zV-Kp-Fdm^sKSls$Ix!1Sp&N4-9C|f9;qb#MEu@yWN?g_$>kQpOW0I|_aI0>_E+zyB zut3BUfG!=yGjyLCWb{6~%0Q(oaV${X`Xbj#8MvVm+@x*$X-c4S delta 416 zcmX>vaa4jkk(ZZ?0SJDcFW$(#gHbF`KQ}ccGg03ou_(o*D6=e8KcF(BWbQ!0Ui5PGsJs~@BK6yhPsYOL{AeDkZLX)jX9>i7v z5sDx}07%?o$xSTIF46(Pexu=!wu2gEf867@h_ z4B|1cu`#kSaxt6Z7@`N$5I3bAq|)w^x4T9Y6D}HK zP%m@$;?<9sy?O9zJopc+dhlX2(L}GFd~eobt=MFKoqccK%!ktz2iC|4B(k zm?nP2^-L*!!}J^uW|c43EMA4QFcR}aY22-(QiyGtR=L4}_75RNvmS9Lkz+mn)5J-} z(&9^U>}U_#1GQ+|tKQl?fDQRbshe9ByIQlZnl_mA@)EB@|K>(=%akapqf8f`dXDw_ zFVzi}>!TIKARi544zDl6rlpmJsB72y$dhNVyM5Dd+TxT!#yx*~!ZXR%i_pN~C)%Q*M*4NM1S(46@``IN*$v4C65@MT?nEht2D6#hKj~m7BoH=mIB|rIt~g7v zID>@0(4AntBWP+(gFdsu&gd-bZ)EPVIXXQ&uoGwbD98vY+vpatwCD*ACxXzSLZ^SJ zhexMmP!26XK|yDgV<9*MiL2b=Pyy0u+m z!8jN{f**MWbaB@>G(rla+Om~4g==MqelYxx##^?&pXR41APHw_euf~65Jc$T!9T+(67^)%6T{x(PG_dZJ`D*tSd8@N&yn03@q1@{JQn)u@&r`|dE! fCJAN delta 1437 zcmZ`(%}*0i5btYiUAk?l4Nyv@K;>(d1QbOrihP5S;0Mu*hD~W7Qfaqjx+UNR55~lp zXv~Xx@lQ|_vj_hH<4wJ9j5p)Ki}9clFV4J80Sh+SUuS3D%=^vn&D)1FcW2aeFz9#T z@At>jYc=m?wzcN|P67==>?vLrmdQ?dQej!FB{b6+NY=d4ku^x#t&3Y2K&xUDtXG2QYJRmcqY(0DA(xMmml-vj| z6%=c}j(b#@bOb%nBR)hM!@Fev8BMa36>FShBgEJC=1dN<9c`bpY-E;g zU$Jbil+9}T1L9@uG#jwK#$GX|h^O(yP!(q)S(Rn0w4oy;|B3OE7r_+>Fc=d*;`4oH zDmj|h;UkNjBkyn}4DnH!Et2Tqh`|jmUz!Pdnq(d34WL+dx}6quswNhzy!V4iqEZ$sYx5bv@9;icpIbu)O46_547JOfD2|Z@BGf)~p%s^+s#}w0M{-66c!3*c8XLkZi=#ktR}}j1^d-f!_M;nn zk?qHHhw(N~X-Tpp7#$==R6l+IH&4Jon)2*wCT S2}oVZamN@}+7a(MrvC!<(G0Nw diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-39.pyc index b3b5a7f213c6eeed94f4918d1559c7feb6ea3776..516fa3645a03ba76d527bfb3d796b5fc02868650 100644 GIT binary patch delta 327 zcmZpZn;^%X$ji&c00i06^EPtdVPTA#{DLJKNV>3s$OWu9K$4fuf-j0Yxj3^p-@?Mw z(kwM6Pc4m4FG@|#j+&gn9srct$gU#FETB%OXCY@+vNtd@b~XN6JjJDX@u{Wp=|!oj*|#Pqum=ETHnOWp-(oAvEG|vV zK{CK1vj}A8t;wI*jex3DIn;rqFNd_&El#Kvh9*$uIf*5id6q?dK;>0jP)S`w(_51# zacHvLV$RObyfyhChd9`Ixrxb{c_sP98Mh`svWya!de(Cvg1$ diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/AUTHORS b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/AUTHORS new file mode 100644 index 00000000..b5e878e2 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/AUTHORS @@ -0,0 +1,9 @@ +# This is the official list of YAPF authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS files. +# See the latter for an explanation. + +# Names should be added to this file as: +# Name or Organization +# The email address is not required for organizations. + +Google Inc. diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/INSTALLER b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/LICENSE b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/METADATA b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/METADATA new file mode 100644 index 00000000..25084e77 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/METADATA @@ -0,0 +1,1026 @@ +Metadata-Version: 2.1 +Name: yapf +Version: 0.31.0 +Summary: A formatter for Python code. +Home-page: UNKNOWN +Author: Google Inc. +Maintainer: Bill Wendling +Maintainer-email: morbo@google.com +License: Apache License, Version 2.0 +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Software Development :: Quality Assurance + +==== +YAPF +==== + +.. image:: https://badge.fury.io/py/yapf.svg + :target: https://badge.fury.io/py/yapf + :alt: PyPI version + +.. image:: https://travis-ci.org/google/yapf.svg?branch=main + :target: https://travis-ci.org/google/yapf + :alt: Build status + +.. image:: https://coveralls.io/repos/google/yapf/badge.svg?branch=main + :target: https://coveralls.io/r/google/yapf?branch=main + :alt: Coverage status + + +Introduction +============ + +Most of the current formatters for Python --- e.g., autopep8, and pep8ify --- +are made to remove lint errors from code. This has some obvious limitations. +For instance, code that conforms to the PEP 8 guidelines may not be +reformatted. But it doesn't mean that the code looks good. + +YAPF takes a different approach. It's based off of `'clang-format' `_, developed by Daniel Jasper. In essence, +the algorithm takes the code and reformats it to the best formatting that +conforms to the style guide, even if the original code didn't violate the +style guide. The idea is also similar to the `'gofmt' `_ tool for the Go programming language: end all holy wars about +formatting - if the whole codebase of a project is simply piped through YAPF +whenever modifications are made, the style remains consistent throughout the +project and there's no point arguing about style in every code review. + +The ultimate goal is that the code YAPF produces is as good as the code that a +programmer would write if they were following the style guide. It takes away +some of the drudgery of maintaining your code. + +.. footer:: + + YAPF is not an official Google product (experimental or otherwise), it is + just code that happens to be owned by Google. + +.. contents:: + + +Installation +============ + +To install YAPF from PyPI: + +.. code-block:: shell + + $ pip install yapf + +(optional) If you are using Python 2.7 and want to enable multiprocessing: + +.. code-block:: shell + + $ pip install futures + +YAPF is still considered in "alpha" stage, and the released version may change +often; therefore, the best way to keep up-to-date with the latest development +is to clone this repository. + +Note that if you intend to use YAPF as a command-line tool rather than as a +library, installation is not necessary. YAPF supports being run as a directory +by the Python interpreter. If you cloned/unzipped YAPF into ``DIR``, it's +possible to run: + +.. code-block:: shell + + $ PYTHONPATH=DIR python DIR/yapf [options] ... + + +Python versions +=============== + +YAPF supports Python 2.7 and 3.6.4+. (Note that some Python 3 features may fail +to parse with Python versions before 3.6.4.) + +YAPF requires the code it formats to be valid Python for the version YAPF itself +runs under. Therefore, if you format Python 3 code with YAPF, run YAPF itself +under Python 3 (and similarly for Python 2). + + +Usage +===== + +Options:: + + usage: yapf [-h] [-v] [-d | -i] [-r | -l START-END] [-e PATTERN] + [--style STYLE] [--style-help] [--no-local-style] [-p] + [-vv] + [files [files ...]] + + Formatter for Python code. + + positional arguments: + files + + optional arguments: + -h, --help show this help message and exit + -v, --version show version number and exit + -d, --diff print the diff for the fixed source + -i, --in-place make changes to files in place + -r, --recursive run recursively over directories + -l START-END, --lines START-END + range of lines to reformat, one-based + -e PATTERN, --exclude PATTERN + patterns for files to exclude from formatting + --style STYLE specify formatting style: either a style name (for + example "pep8" or "google"), or the name of a file + with style settings. The default is pep8 unless a + .style.yapf or setup.cfg or pyproject.toml file + located in the same directory as the source or one of + its parent directories (for stdin, the current + directory is used). + --style-help show style settings and exit; this output can be saved + to .style.yapf to make your settings permanent + --no-local-style don't search for local style definition + -p, --parallel Run yapf in parallel when formatting multiple files. + Requires concurrent.futures in Python 2.X + -vv, --verbose Print out file names while processing + + +------------ +Return Codes +------------ + +Normally YAPF returns zero on successful program termination and non-zero otherwise. + +If ``--diff`` is supplied, YAPF returns zero when no changes were necessary, non-zero +otherwise (including program error). You can use this in a CI workflow to test that code +has been YAPF-formatted. + +--------------------------------------------- +Excluding files from formatting (.yapfignore) +--------------------------------------------- + +In addition to exclude patterns provided on commandline, YAPF looks for additional +patterns specified in a file named ``.yapfignore`` located in the working directory from +which YAPF is invoked. + +``.yapfignore``'s syntax is similar to UNIX's filename pattern matching:: + + * matches everything + ? matches any single character + [seq] matches any character in seq + [!seq] matches any character not in seq + +Note that no entry should begin with `./`. + + +Formatting style +================ + +The formatting style used by YAPF is configurable and there are many "knobs" +that can be used to tune how YAPF does formatting. See the ``style.py`` module +for the full list. + +To control the style, run YAPF with the ``--style`` argument. It accepts one of +the predefined styles (e.g., ``pep8`` or ``google``), a path to a configuration +file that specifies the desired style, or a dictionary of key/value pairs. + +The config file is a simple listing of (case-insensitive) ``key = value`` pairs +with a ``[yapf]`` heading. For example: + +.. code-block:: ini + + [yapf] + based_on_style = pep8 + spaces_before_comment = 4 + split_before_logical_operator = true + +The ``based_on_style`` setting determines which of the predefined styles this +custom style is based on (think of it like subclassing). Four +styles are predefined: + +- ``pep8`` (default) +- ``google`` (based off of the `Google Python Style Guide`_) +- ``yapf`` (for use with Google open source projects) +- ``facebook`` + +.. _`Google Python Style Guide`: https://github.com/google/styleguide/blob/gh-pages/pyguide.md + +See ``_STYLE_NAME_TO_FACTORY`` in style.py_ for details. + +.. _style.py: https://github.com/google/yapf/blob/main/yapf/yapflib/style.py + +It's also possible to do the same on the command line with a dictionary. For +example: + +.. code-block:: shell + + --style='{based_on_style: pep8, indent_width: 2}' + +This will take the ``pep8`` base style and modify it to have two space +indentations. + +YAPF will search for the formatting style in the following manner: + +1. Specified on the command line +2. In the ``[style]`` section of a ``.style.yapf`` file in either the current + directory or one of its parent directories. +3. In the ``[yapf]`` section of a ``setup.cfg`` file in either the current + directory or one of its parent directories. +4. In the ``[tool.yapf]`` section of a ``pyproject.toml`` file in either the current + directory or one of its parent directories. +5. In the ``[style]`` section of a ``~/.config/yapf/style`` file in your home + directory. + +If none of those files are found, the default style is used (PEP8). + + +Example +======= + +An example of the type of formatting that YAPF can do, it will take this ugly +code: + +.. code-block:: python + + x = { 'a':37,'b':42, + + 'c':927} + + y = 'hello ''world' + z = 'hello '+'world' + a = 'hello {}'.format('world') + class foo ( object ): + def f (self ): + return 37*-+2 + def g(self, x,y=42): + return y + def f ( a ) : + return 37+-+a[42-x : y**3] + +and reformat it into: + +.. code-block:: python + + x = {'a': 37, 'b': 42, 'c': 927} + + y = 'hello ' 'world' + z = 'hello ' + 'world' + a = 'hello {}'.format('world') + + + class foo(object): + def f(self): + return 37 * -+2 + + def g(self, x, y=42): + return y + + + def f(a): + return 37 + -+a[42 - x:y**3] + + +Example as a module +=================== + +The two main APIs for calling yapf are ``FormatCode`` and ``FormatFile``, these +share several arguments which are described below: + +.. code-block:: python + + >>> from yapf.yapflib.yapf_api import FormatCode # reformat a string of code + + >>> FormatCode("f ( a = 1, b = 2 )") + 'f(a=1, b=2)\n' + +A ``style_config`` argument: Either a style name or a path to a file that contains +formatting style settings. If None is specified, use the default style +as set in ``style.DEFAULT_STYLE_FACTORY``. + +.. code-block:: python + + >>> FormatCode("def g():\n return True", style_config='pep8') + 'def g():\n return True\n' + +A ``lines`` argument: A list of tuples of lines (ints), [start, end], +that we want to format. The lines are 1-based indexed. It can be used by +third-party code (e.g., IDEs) when reformatting a snippet of code rather +than a whole file. + +.. code-block:: python + + >>> FormatCode("def g( ):\n a=1\n b = 2\n return a==b", lines=[(1, 1), (2, 3)]) + 'def g():\n a = 1\n b = 2\n return a==b\n' + +A ``print_diff`` (bool): Instead of returning the reformatted source, return a +diff that turns the formatted source into reformatter source. + +.. code-block:: python + + >>> print(FormatCode("a==b", filename="foo.py", print_diff=True)) + --- foo.py (original) + +++ foo.py (reformatted) + @@ -1 +1 @@ + -a==b + +a == b + +Note: the ``filename`` argument for ``FormatCode`` is what is inserted into +the diff, the default is ````. + +``FormatFile`` returns reformatted code from the passed file along with its encoding: + +.. code-block:: python + + >>> from yapf.yapflib.yapf_api import FormatFile # reformat a file + + >>> print(open("foo.py").read()) # contents of file + a==b + + >>> FormatFile("foo.py") + ('a == b\n', 'utf-8') + +The ``in_place`` argument saves the reformatted code back to the file: + +.. code-block:: python + + >>> FormatFile("foo.py", in_place=True) + (None, 'utf-8') + + >>> print(open("foo.py").read()) # contents of file (now fixed) + a == b + +Formatting diffs +================ + +Options:: + + usage: yapf-diff [-h] [-i] [-p NUM] [--regex PATTERN] [--iregex PATTERN][-v] + [--style STYLE] [--binary BINARY] + + This script reads input from a unified diff and reformats all the changed + lines. This is useful to reformat all the lines touched by a specific patch. + Example usage for git/svn users: + + git diff -U0 --no-color --relative HEAD^ | yapf-diff -i + svn diff --diff-cmd=diff -x-U0 | yapf-diff -p0 -i + + It should be noted that the filename contained in the diff is used + unmodified to determine the source file to update. Users calling this script + directly should be careful to ensure that the path in the diff is correct + relative to the current working directory. + + optional arguments: + -h, --help show this help message and exit + -i, --in-place apply edits to files instead of displaying a diff + -p NUM, --prefix NUM strip the smallest prefix containing P slashes + --regex PATTERN custom pattern selecting file paths to reformat + (case sensitive, overrides -iregex) + --iregex PATTERN custom pattern selecting file paths to reformat + (case insensitive, overridden by -regex) + -v, --verbose be more verbose, ineffective without -i + --style STYLE specify formatting style: either a style name (for + example "pep8" or "google"), or the name of a file + with style settings. The default is pep8 unless a + .style.yapf or setup.cfg or pyproject.toml file + located in the same directory as the source or one of + its parent directories (for stdin, the current + directory is used). + --binary BINARY location of binary to use for yapf + +Knobs +===== + +``ALIGN_CLOSING_BRACKET_WITH_VISUAL_INDENT`` + Align closing bracket with visual indentation. + +``ALLOW_MULTILINE_LAMBDAS`` + Allow lambdas to be formatted on more than one line. + +``ALLOW_MULTILINE_DICTIONARY_KEYS`` + Allow dictionary keys to exist on multiple lines. For example: + + .. code-block:: python + + x = { + ('this is the first element of a tuple', + 'this is the second element of a tuple'): + value, + } + +``ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS`` + Allow splitting before a default / named assignment in an argument list. + +``ALLOW_SPLIT_BEFORE_DICT_VALUE`` + Allow splits before the dictionary value. + +``ARITHMETIC_PRECEDENCE_INDICATION`` + Let spacing indicate operator precedence. For example: + + .. code-block:: python + + a = 1 * 2 + 3 / 4 + b = 1 / 2 - 3 * 4 + c = (1 + 2) * (3 - 4) + d = (1 - 2) / (3 + 4) + e = 1 * 2 - 3 + f = 1 + 2 + 3 + 4 + + will be formatted as follows to indicate precedence: + + .. code-block:: python + + a = 1*2 + 3/4 + b = 1/2 - 3*4 + c = (1+2) * (3-4) + d = (1-2) / (3+4) + e = 1*2 - 3 + f = 1 + 2 + 3 + 4 + +``BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF`` + Insert a blank line before a ``def`` or ``class`` immediately nested within + another ``def`` or ``class``. For example: + + .. code-block:: python + + class Foo: + # <------ this blank line + def method(): + pass + +``BLANK_LINE_BEFORE_MODULE_DOCSTRING`` + Insert a blank line before a module docstring. + +``BLANK_LINE_BEFORE_CLASS_DOCSTRING`` + Insert a blank line before a class-level docstring. + +``BLANK_LINES_AROUND_TOP_LEVEL_DEFINITION`` + Sets the number of desired blank lines surrounding top-level function and + class definitions. For example: + + .. code-block:: python + + class Foo: + pass + # <------ having two blank lines here + # <------ is the default setting + class Bar: + pass + +``BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES`` + Sets the number of desired blank lines between top-level imports and + variable definitions. Useful for compatibility with tools like isort. + +``COALESCE_BRACKETS`` + Do not split consecutive brackets. Only relevant when + ``DEDENT_CLOSING_BRACKETS`` or ``INDENT_CLOSING_BRACKETS`` + is set. For example: + + .. code-block:: python + + call_func_that_takes_a_dict( + { + 'key1': 'value1', + 'key2': 'value2', + } + ) + + would reformat to: + + .. code-block:: python + + call_func_that_takes_a_dict({ + 'key1': 'value1', + 'key2': 'value2', + }) + + +``COLUMN_LIMIT`` + The column limit (or max line-length) + +``CONTINUATION_ALIGN_STYLE`` + The style for continuation alignment. Possible values are: + + - ``SPACE``: Use spaces for continuation alignment. This is default + behavior. + - ``FIXED``: Use fixed number (CONTINUATION_INDENT_WIDTH) of columns + (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs or CONTINUATION_INDENT_WIDTH + spaces) for continuation alignment. + - ``VALIGN-RIGHT``: Vertically align continuation lines to multiple of + INDENT_WIDTH columns. Slightly right (one tab or a few spaces) if cannot + vertically align continuation lines with indent characters. + +``CONTINUATION_INDENT_WIDTH`` + Indent width used for line continuations. + +``DEDENT_CLOSING_BRACKETS`` + Put closing brackets on a separate line, dedented, if the bracketed + expression can't fit in a single line. Applies to all kinds of brackets, + including function definitions and calls. For example: + + .. code-block:: python + + config = { + 'key1': 'value1', + 'key2': 'value2', + } # <--- this bracket is dedented and on a separate line + + time_series = self.remote_client.query_entity_counters( + entity='dev3246.region1', + key='dns.query_latency_tcp', + transform=Transformation.AVERAGE(window=timedelta(seconds=60)), + start_ts=now()-timedelta(days=3), + end_ts=now(), + ) # <--- this bracket is dedented and on a separate line + +``DISABLE_ENDING_COMMA_HEURISTIC`` + Disable the heuristic which places each list element on a separate line if + the list is comma-terminated. + +``EACH_DICT_ENTRY_ON_SEPARATE_LINE`` + Place each dictionary entry onto its own line. + +``FORCE_MULTILINE_DICT`` + Respect EACH_DICT_ENTRY_ON_SEPARATE_LINE even if the line is shorter than + COLUMN_LIMIT. + +``I18N_COMMENT`` + The regex for an internationalization comment. The presence of this comment + stops reformatting of that line, because the comments are required to be + next to the string they translate. + +``I18N_FUNCTION_CALL`` + The internationalization function call names. The presence of this function + stops reformatting on that line, because the string it has cannot be moved + away from the i18n comment. + +``INDENT_DICTIONARY_VALUE`` + Indent the dictionary value if it cannot fit on the same line as the + dictionary key. For example: + + .. code-block:: python + + config = { + 'key1': + 'value1', + 'key2': value1 + + value2, + } + +``INDENT_WIDTH`` + The number of columns to use for indentation. + +``INDENT_BLANK_LINES`` + Set to ``True`` to prefer indented blank lines rather than empty + +``INDENT_CLOSING_BRACKETS`` + Put closing brackets on a separate line, indented, if the bracketed + expression can't fit in a single line. Applies to all kinds of brackets, + including function definitions and calls. For example: + + .. code-block:: python + + config = { + 'key1': 'value1', + 'key2': 'value2', + } # <--- this bracket is indented and on a separate line + + time_series = self.remote_client.query_entity_counters( + entity='dev3246.region1', + key='dns.query_latency_tcp', + transform=Transformation.AVERAGE(window=timedelta(seconds=60)), + start_ts=now()-timedelta(days=3), + end_ts=now(), + ) # <--- this bracket is indented and on a separate line + +``JOIN_MULTIPLE_LINES`` + Join short lines into one line. E.g., single line ``if`` statements. + +``NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS`` + Do not include spaces around selected binary operators. For example: + + .. code-block:: python + + 1 + 2 * 3 - 4 / 5 + + will be formatted as follows when configured with ``*``, ``/``: + + .. code-block:: python + + 1 + 2*3 - 4/5 + +``SPACES_AROUND_POWER_OPERATOR`` + Set to ``True`` to prefer using spaces around ``**``. + +``SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN`` + Set to ``True`` to prefer spaces around the assignment operator for default + or keyword arguments. + +``SPACES_AROUND_DICT_DELIMITERS`` + Adds a space after the opening '{' and before the ending '}' dict delimiters. + + .. code-block:: python + + {1: 2} + + will be formatted as: + + .. code-block:: python + + { 1: 2 } + +``SPACES_AROUND_LIST_DELIMITERS`` + Adds a space after the opening '[' and before the ending ']' list delimiters. + + .. code-block:: python + + [1, 2] + + will be formatted as: + + .. code-block:: python + + [ 1, 2 ] + +``SPACES_AROUND_SUBSCRIPT_COLON`` + Use spaces around the subscript / slice operator. For example: + + .. code-block:: python + + my_list[1 : 10 : 2] + +``SPACES_AROUND_TUPLE_DELIMITERS`` + Adds a space after the opening '(' and before the ending ')' tuple delimiters. + + .. code-block:: python + + (1, 2, 3) + + will be formatted as: + + .. code-block:: python + + ( 1, 2, 3 ) + +``SPACES_BEFORE_COMMENT`` + The number of spaces required before a trailing comment. + This can be a single value (representing the number of spaces + before each trailing comment) or list of of values (representing + alignment column values; trailing comments within a block will + be aligned to the first column value that is greater than the maximum + line length within the block). For example: + + With ``spaces_before_comment=5``: + + .. code-block:: python + + 1 + 1 # Adding values + + will be formatted as: + + .. code-block:: python + + 1 + 1 # Adding values <-- 5 spaces between the end of the statement and comment + + With ``spaces_before_comment=15, 20``: + + .. code-block:: python + + 1 + 1 # Adding values + two + two # More adding + + longer_statement # This is a longer statement + short # This is a shorter statement + + a_very_long_statement_that_extends_beyond_the_final_column # Comment + short # This is a shorter statement + + will be formatted as: + + .. code-block:: python + + 1 + 1 # Adding values <-- end of line comments in block aligned to col 15 + two + two # More adding + + longer_statement # This is a longer statement <-- end of line comments in block aligned to col 20 + short # This is a shorter statement + + a_very_long_statement_that_extends_beyond_the_final_column # Comment <-- the end of line comments are aligned based on the line length + short # This is a shorter statement + +``SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET`` + Insert a space between the ending comma and closing bracket of a list, etc. + +``SPACE_INSIDE_BRACKETS`` + Use spaces inside brackets, braces, and parentheses. For example: + + .. code-block:: python + + method_call( 1 ) + my_dict[ 3 ][ 1 ][ get_index( *args, **kwargs ) ] + my_set = { 1, 2, 3 } + +``SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED`` + Split before arguments if the argument list is terminated by a comma. + +``SPLIT_ALL_COMMA_SEPARATED_VALUES`` + If a comma separated list (``dict``, ``list``, ``tuple``, or function + ``def``) is on a line that is too long, split such that all elements + are on a single line. + +``SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES`` + Variation on ``SPLIT_ALL_COMMA_SEPARATED_VALUES`` in which, if a + subexpression with a comma fits in its starting line, then the + subexpression is not split. This avoids splits like the one for + ``b`` in this code: + + .. code-block:: python + + abcdef( + aReallyLongThing: int, + b: [Int, + Int]) + + With the new knob this is split as: + + .. code-block:: python + + abcdef( + aReallyLongThing: int, + b: [Int, Int]) + +``SPLIT_BEFORE_BITWISE_OPERATOR`` + Set to ``True`` to prefer splitting before ``&``, ``|`` or ``^`` rather + than after. + +``SPLIT_BEFORE_ARITHMETIC_OPERATOR`` + Set to ``True`` to prefer splitting before ``+``, ``-``, ``*``, ``/``, ``//``, + or ``@`` rather than after. + +``SPLIT_BEFORE_CLOSING_BRACKET`` + Split before the closing bracket if a ``list`` or ``dict`` literal doesn't + fit on a single line. + +``SPLIT_BEFORE_DICT_SET_GENERATOR`` + Split before a dictionary or set generator (comp_for). For example, note + the split before the ``for``: + + .. code-block:: python + + foo = { + variable: 'Hello world, have a nice day!' + for variable in bar if variable != 42 + } + +``SPLIT_BEFORE_DOT`` + Split before the ``.`` if we need to split a longer expression: + + .. code-block:: python + + foo = ('This is a really long string: {}, {}, {}, {}'.format(a, b, c, d)) + + would reformat to something like: + + .. code-block:: python + + foo = ('This is a really long string: {}, {}, {}, {}' + .format(a, b, c, d)) + +``SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN`` + Split after the opening paren which surrounds an expression if it doesn't + fit on a single line. + +``SPLIT_BEFORE_FIRST_ARGUMENT`` + If an argument / parameter list is going to be split, then split before the + first argument. + +``SPLIT_BEFORE_LOGICAL_OPERATOR`` + Set to ``True`` to prefer splitting before ``and`` or ``or`` rather than + after. + +``SPLIT_BEFORE_NAMED_ASSIGNS`` + Split named assignments onto individual lines. + +``SPLIT_COMPLEX_COMPREHENSION`` + For list comprehensions and generator expressions with multiple clauses + (e.g multiple ``for`` calls, ``if`` filter expressions) and which need to + be reflowed, split each clause onto its own line. For example: + + .. code-block:: python + + result = [ + a_var + b_var for a_var in xrange(1000) for b_var in xrange(1000) + if a_var % b_var] + + would reformat to something like: + + .. code-block:: python + + result = [ + a_var + b_var + for a_var in xrange(1000) + for b_var in xrange(1000) + if a_var % b_var] + +``SPLIT_PENALTY_AFTER_OPENING_BRACKET`` + The penalty for splitting right after the opening bracket. + +``SPLIT_PENALTY_AFTER_UNARY_OPERATOR`` + The penalty for splitting the line after a unary operator. + +``SPLIT_PENALTY_ARITHMETIC_OPERATOR`` + The penalty of splitting the line around the ``+``, ``-``, ``*``, ``/``, + ``//``, ``%``, and ``@`` operators. + +``SPLIT_PENALTY_BEFORE_IF_EXPR`` + The penalty for splitting right before an ``if`` expression. + +``SPLIT_PENALTY_BITWISE_OPERATOR`` + The penalty of splitting the line around the ``&``, ``|``, and ``^`` + operators. + +``SPLIT_PENALTY_COMPREHENSION`` + The penalty for splitting a list comprehension or generator expression. + +``SPLIT_PENALTY_EXCESS_CHARACTER`` + The penalty for characters over the column limit. + +``SPLIT_PENALTY_FOR_ADDED_LINE_SPLIT`` + The penalty incurred by adding a line split to the unwrapped line. The more + line splits added the higher the penalty. + +``SPLIT_PENALTY_IMPORT_NAMES`` + The penalty of splitting a list of ``import as`` names. For example: + + .. code-block:: python + + from a_very_long_or_indented_module_name_yada_yad import (long_argument_1, + long_argument_2, + long_argument_3) + + would reformat to something like: + + .. code-block:: python + + from a_very_long_or_indented_module_name_yada_yad import ( + long_argument_1, long_argument_2, long_argument_3) + +``SPLIT_PENALTY_LOGICAL_OPERATOR`` + The penalty of splitting the line around the ``and`` and ``or`` operators. + +``USE_TABS`` + Use the Tab character for indentation. + +(Potentially) Frequently Asked Questions +======================================== + +-------------------------------------------- +Why does YAPF destroy my awesome formatting? +-------------------------------------------- + +YAPF tries very hard to get the formatting correct. But for some code, it won't +be as good as hand-formatting. In particular, large data literals may become +horribly disfigured under YAPF. + +The reasons for this are manyfold. In short, YAPF is simply a tool to help +with development. It will format things to coincide with the style guide, but +that may not equate with readability. + +What can be done to alleviate this situation is to indicate regions YAPF should +ignore when reformatting something: + +.. code-block:: python + + # yapf: disable + FOO = { + # ... some very large, complex data literal. + } + + BAR = [ + # ... another large data literal. + ] + # yapf: enable + +You can also disable formatting for a single literal like this: + +.. code-block:: python + + BAZ = { + (1, 2, 3, 4), + (5, 6, 7, 8), + (9, 10, 11, 12), + } # yapf: disable + +To preserve the nice dedented closing brackets, use the +``dedent_closing_brackets`` in your style. Note that in this case all +brackets, including function definitions and calls, are going to use +that style. This provides consistency across the formatted codebase. + +------------------------------- +Why Not Improve Existing Tools? +------------------------------- + +We wanted to use clang-format's reformatting algorithm. It's very powerful and +designed to come up with the best formatting possible. Existing tools were +created with different goals in mind, and would require extensive modifications +to convert to using clang-format's algorithm. + +----------------------------- +Can I Use YAPF In My Program? +----------------------------- + +Please do! YAPF was designed to be used as a library as well as a command line +tool. This means that a tool or IDE plugin is free to use YAPF. + +----------------------------------------- +I still get non Pep8 compliant code! Why? +----------------------------------------- + +YAPF tries very hard to be fully PEP 8 compliant. However, it is paramount +to not risk altering the semantics of your code. Thus, YAPF tries to be as +safe as possible and does not change the token stream +(e.g., by adding parentheses). +All these cases however, can be easily fixed manually. For instance, + +.. code-block:: python + + from my_package import my_function_1, my_function_2, my_function_3, my_function_4, my_function_5 + + FOO = my_variable_1 + my_variable_2 + my_variable_3 + my_variable_4 + my_variable_5 + my_variable_6 + my_variable_7 + my_variable_8 + +won't be split, but you can easily get it right by just adding parentheses: + +.. code-block:: python + + from my_package import (my_function_1, my_function_2, my_function_3, + my_function_4, my_function_5) + + FOO = (my_variable_1 + my_variable_2 + my_variable_3 + my_variable_4 + + my_variable_5 + my_variable_6 + my_variable_7 + my_variable_8) + +Gory Details +============ + +---------------- +Algorithm Design +---------------- + +The main data structure in YAPF is the ``UnwrappedLine`` object. It holds a list +of ``FormatToken``\s, that we would want to place on a single line if there were +no column limit. An exception being a comment in the middle of an expression +statement will force the line to be formatted on more than one line. The +formatter works on one ``UnwrappedLine`` object at a time. + +An ``UnwrappedLine`` typically won't affect the formatting of lines before or +after it. There is a part of the algorithm that may join two or more +``UnwrappedLine``\s into one line. For instance, an if-then statement with a +short body can be placed on a single line: + +.. code-block:: python + + if a == 42: continue + +YAPF's formatting algorithm creates a weighted tree that acts as the solution +space for the algorithm. Each node in the tree represents the result of a +formatting decision --- i.e., whether to split or not to split before a token. +Each formatting decision has a cost associated with it. Therefore, the cost is +realized on the edge between two nodes. (In reality, the weighted tree doesn't +have separate edge objects, so the cost resides on the nodes themselves.) + +For example, take the following Python code snippet. For the sake of this +example, assume that line (1) violates the column limit restriction and needs to +be reformatted. + +.. code-block:: python + + def xxxxxxxxxxx(aaaaaaaaaaaa, bbbbbbbbb, cccccccc, dddddddd, eeeeee): # 1 + pass # 2 + +For line (1), the algorithm will build a tree where each node (a +``FormattingDecisionState`` object) is the state of the line at that token given +the decision to split before the token or not. Note: the ``FormatDecisionState`` +objects are copied by value so each node in the graph is unique and a change in +one doesn't affect other nodes. + +Heuristics are used to determine the costs of splitting or not splitting. +Because a node holds the state of the tree up to a token's insertion, it can +easily determine if a splitting decision will violate one of the style +requirements. For instance, the heuristic is able to apply an extra penalty to +the edge when not splitting between the previous token and the one being added. + +There are some instances where we will never want to split the line, because +doing so will always be detrimental (i.e., it will require a backslash-newline, +which is very rarely desirable). For line (1), we will never want to split the +first three tokens: ``def``, ``xxxxxxxxxxx``, and ``(``. Nor will we want to +split between the ``)`` and the ``:`` at the end. These regions are said to be +"unbreakable." This is reflected in the tree by there not being a "split" +decision (left hand branch) within the unbreakable region. + +Now that we have the tree, we determine what the "best" formatting is by finding +the path through the tree with the lowest cost. + +And that's it! + + diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/RECORD b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/RECORD new file mode 100644 index 00000000..80f251f3 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/RECORD @@ -0,0 +1,109 @@ +../../../bin/yapf,sha256=lTrSuTNHC4wRp4JTRdvC-oXOXT3OyJ0-fU6hTkWLx-U,265 +../../../bin/yapf-diff,sha256=wKsx179txoWfvEitvShxtccgP2-hof0fJ0lxLdwc6FI,289 +yapf-0.31.0.dist-info/AUTHORS,sha256=GjWR8Xly-Dl9VrKuzTLOvRoCbMNy278DxK2Sud9LcCw,307 +yapf-0.31.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +yapf-0.31.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358 +yapf-0.31.0.dist-info/METADATA,sha256=LVZ2UdIdDWvcyZvycrgLTvTQgk2I3p9lg5Uu49jWAYA,34036 +yapf-0.31.0.dist-info/RECORD,, +yapf-0.31.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +yapf-0.31.0.dist-info/WHEEL,sha256=8zNYZbwQSXoB9IfXOjPfeNwvAsALAjffgk27FqvCWbo,110 +yapf-0.31.0.dist-info/entry_points.txt,sha256=fc7WCcYyJWR7Twl8ubci_UQz4gt-U9VYkXKDZODxEHA,94 +yapf-0.31.0.dist-info/top_level.txt,sha256=Y1sKm3Or1-KlBNXU8zv3IuXSJx1lAU-I_Cv_qTNq-WQ,15 +yapf/__init__.py,sha256=vQ4lF_BZ0lW_KZF7-77Cljs8uZaSmMyflcZ4Q-xpYJg,12493 +yapf/__main__.py,sha256=jJ5Fcwe6tbXxqSuUxRO3uel44tHP53vVScojlus0cBM,680 +yapf/__pycache__/__init__.cpython-39.pyc,, +yapf/__pycache__/__main__.cpython-39.pyc,, +yapf/yapflib/__init__.py,sha256=abBqhqqPP10jK6pNCEt5VDVZfYK0u0fQugTp2AC0K4k,596 +yapf/yapflib/__pycache__/__init__.cpython-39.pyc,, +yapf/yapflib/__pycache__/blank_line_calculator.cpython-39.pyc,, +yapf/yapflib/__pycache__/comment_splicer.cpython-39.pyc,, +yapf/yapflib/__pycache__/continuation_splicer.cpython-39.pyc,, +yapf/yapflib/__pycache__/errors.cpython-39.pyc,, +yapf/yapflib/__pycache__/file_resources.cpython-39.pyc,, +yapf/yapflib/__pycache__/format_decision_state.cpython-39.pyc,, +yapf/yapflib/__pycache__/format_token.cpython-39.pyc,, +yapf/yapflib/__pycache__/identify_container.cpython-39.pyc,, +yapf/yapflib/__pycache__/line_joiner.cpython-39.pyc,, +yapf/yapflib/__pycache__/object_state.cpython-39.pyc,, +yapf/yapflib/__pycache__/py3compat.cpython-39.pyc,, +yapf/yapflib/__pycache__/pytree_unwrapper.cpython-39.pyc,, +yapf/yapflib/__pycache__/pytree_utils.cpython-39.pyc,, +yapf/yapflib/__pycache__/pytree_visitor.cpython-39.pyc,, +yapf/yapflib/__pycache__/reformatter.cpython-39.pyc,, +yapf/yapflib/__pycache__/split_penalty.cpython-39.pyc,, +yapf/yapflib/__pycache__/style.cpython-39.pyc,, +yapf/yapflib/__pycache__/subtype_assigner.cpython-39.pyc,, +yapf/yapflib/__pycache__/unwrapped_line.cpython-39.pyc,, +yapf/yapflib/__pycache__/verifier.cpython-39.pyc,, +yapf/yapflib/__pycache__/yapf_api.cpython-39.pyc,, +yapf/yapflib/blank_line_calculator.py,sha256=BIjdJNXN-jbYak17yM-GG1cTgntlRMxgfr7tm1w7ZC4,6297 +yapf/yapflib/comment_splicer.py,sha256=zZ3NQNgSACygyvc-zJb_wsdL1E_WcP-kwXYPHANGY4I,15240 +yapf/yapflib/continuation_splicer.py,sha256=5_Npzn98SLISqopH2hB3dSTBDVVs_iuCZBd-NJTNOKc,1776 +yapf/yapflib/errors.py,sha256=_fQDh4NEOXANkcm-Y7FobBI6g19szgqR38Hfy_Fmiqw,843 +yapf/yapflib/file_resources.py,sha256=RTMBisikbhupG-oYfr9YM4p2eXWO-NFCiidwia-UeDM,8570 +yapf/yapflib/format_decision_state.py,sha256=MM6qXrBNBUVizlmdIn36pEu7JmVdGTeSwh1IjvVEDEE,48673 +yapf/yapflib/format_token.py,sha256=KGCuDte6k11jBWXmB99o2DhNpvg0JKuedRlkdhDmQQI,12355 +yapf/yapflib/identify_container.py,sha256=ILh2GgBrcmQMvz0g9wPBzIQsOJG1KlmD_mAUR3SruHM,2279 +yapf/yapflib/line_joiner.py,sha256=jAc7Gt6sIbcbVy23y6fyD8l8jXMIyWmP4fWTSTThlew,3924 +yapf/yapflib/object_state.py,sha256=qO18NO2tpgJ9EegxD7DwccGy2PKFymg7lAyffMdY54E,8130 +yapf/yapflib/py3compat.py,sha256=nEKVr2KdYf-fXubA01E88ORixSy7AEUBKoZJOw6ZmfA,4228 +yapf/yapflib/pytree_unwrapper.py,sha256=6gODwJkN5j24jjl2UdhakaNbbm5tzeHRx3TVdH50Gzk,14899 +yapf/yapflib/pytree_utils.py,sha256=DvvGIOmN3C3PzvLqpeSEfaCtDq3075fcOTT22EKrc-Q,10864 +yapf/yapflib/pytree_visitor.py,sha256=qzH-34TqPA776YQIiVv63SfYRlOuxJiH2x3ynLxshmE,4528 +yapf/yapflib/reformatter.py,sha256=H3EaOpZ9YAd5q91cJGxMCW27gqdi78-OT5RMcbeHq9o,28773 +yapf/yapflib/split_penalty.py,sha256=cTqWMa0q_IBkM3q33upQyS2XqkLdcjoHdCaNqnPQGrA,24450 +yapf/yapflib/style.py,sha256=uXM1_0O6N_wpGqDEYbVca0Mp9ah-FTinJuMBnwCqFyY,31772 +yapf/yapflib/subtype_assigner.py,sha256=HlGVcJhmPj1r4DRSP8Nz0JHz-cLbgTCnZzPyW5YRiQE,20220 +yapf/yapflib/unwrapped_line.py,sha256=z9ug5YteMfYvBDp74w55wljXgGChcxykZ4Bt5u6hlpA,25819 +yapf/yapflib/verifier.py,sha256=qT5jlM1j96jeV7YwpdCczKX8vKm51I41TE1mkLX8dkk,3042 +yapf/yapflib/yapf_api.py,sha256=acHd6Mqglnz23VMwHuz2PaBfLn5aCaH0EZSqxowj01Y,10902 +yapftests/__init__.py,sha256=abBqhqqPP10jK6pNCEt5VDVZfYK0u0fQugTp2AC0K4k,596 +yapftests/__pycache__/__init__.cpython-39.pyc,, +yapftests/__pycache__/blank_line_calculator_test.cpython-39.pyc,, +yapftests/__pycache__/comment_splicer_test.cpython-39.pyc,, +yapftests/__pycache__/file_resources_test.cpython-39.pyc,, +yapftests/__pycache__/format_decision_state_test.cpython-39.pyc,, +yapftests/__pycache__/format_token_test.cpython-39.pyc,, +yapftests/__pycache__/line_joiner_test.cpython-39.pyc,, +yapftests/__pycache__/main_test.cpython-39.pyc,, +yapftests/__pycache__/pytree_unwrapper_test.cpython-39.pyc,, +yapftests/__pycache__/pytree_utils_test.cpython-39.pyc,, +yapftests/__pycache__/pytree_visitor_test.cpython-39.pyc,, +yapftests/__pycache__/reformatter_basic_test.cpython-39.pyc,, +yapftests/__pycache__/reformatter_buganizer_test.cpython-39.pyc,, +yapftests/__pycache__/reformatter_facebook_test.cpython-39.pyc,, +yapftests/__pycache__/reformatter_pep8_test.cpython-39.pyc,, +yapftests/__pycache__/reformatter_python3_test.cpython-39.pyc,, +yapftests/__pycache__/reformatter_style_config_test.cpython-39.pyc,, +yapftests/__pycache__/reformatter_verify_test.cpython-39.pyc,, +yapftests/__pycache__/split_penalty_test.cpython-39.pyc,, +yapftests/__pycache__/style_test.cpython-39.pyc,, +yapftests/__pycache__/subtype_assigner_test.cpython-39.pyc,, +yapftests/__pycache__/unwrapped_line_test.cpython-39.pyc,, +yapftests/__pycache__/utils.cpython-39.pyc,, +yapftests/__pycache__/yapf_test.cpython-39.pyc,, +yapftests/__pycache__/yapf_test_helper.cpython-39.pyc,, +yapftests/blank_line_calculator_test.py,sha256=gFd4ZB07U5vrjMKQokyGgKqQWrVD2Xy0VegYAJdXZ94,9157 +yapftests/comment_splicer_test.py,sha256=smvYTJaG99DLdK7nUcLZqCLuJxnzuqQUDmDfujGl3qg,11005 +yapftests/file_resources_test.py,sha256=PycS_nslonsWNHTaCMskA55ARgsA3M3kDTkqfyYGEfw,16831 +yapftests/format_decision_state_test.py,sha256=-TP1msflnJSN3tOX1tqXZCO_73OSm8xsbeu-z9AdDlA,4422 +yapftests/format_token_test.py,sha256=50pv1Gll3nHcPKqa-ycK9dNyrzWFvfZQPYCXt82Oz-g,2899 +yapftests/line_joiner_test.py,sha256=XPGvgP-yvbWGO7MoPZc1wsIhimV-o73MAireSHF_K_M,2616 +yapftests/main_test.py,sha256=XJdvrvhxJ7LfbeHobIWbByIo3DG12v0W9VpItMJbgl0,4174 +yapftests/pytree_unwrapper_test.py,sha256=nBfqDrSpbIzC0ukiecq6P-vXcY_AXQrIPRD_eZ-nHrQ,9368 +yapftests/pytree_utils_test.py,sha256=5NeI1iorER5zipo_CwIsm5FBWtWqeeOjalygUMNaWas,8140 +yapftests/pytree_visitor_test.py,sha256=ljVsmUmIDNGnOpbgoEOmYL6SV-KAIDZoNfiALbKhrP0,4068 +yapftests/reformatter_basic_test.py,sha256=j6E_gPKdjIS8DvTyKcyFD-O0QQt3W_jLLofJ89eRU7c,109414 +yapftests/reformatter_buganizer_test.py,sha256=_vKdQnTEaKwr0PTdi3tTz6i42DvQTQFh_YVa9kd9SHU,86368 +yapftests/reformatter_facebook_test.py,sha256=4G48CTQRLdBVieXSqhQs5U-6pNx0-C8Wjo2bMB5weDI,15205 +yapftests/reformatter_pep8_test.py,sha256=CM5M31rt6tZybbHYJ_j8_K1aZ02qXGUkNillMtch-nk,32620 +yapftests/reformatter_python3_test.py,sha256=PxBeDahwz9RCxLkxaPYvfrHwlBfWN9xsf0rO_WNBkH4,14355 +yapftests/reformatter_style_config_test.py,sha256=6qUvf0gQX29fNS55mIDREQGMjDPTeo_bxDTdmoicEX0,7219 +yapftests/reformatter_verify_test.py,sha256=GbyweTg98AOuV-H5sHdIMOo4q7JV4hJGul4lzsiKuJg,3579 +yapftests/split_penalty_test.py,sha256=oMFpOlCXFxdFUL54npVVkQa3-CfYy3EowQCDbyqhYJI,7417 +yapftests/style_test.py,sha256=I_-yqomVusqtkB3_NO3OiUngx5PAoVBr7maETEN0cgc,11568 +yapftests/subtype_assigner_test.py,sha256=Dab-QW39T-M4k7Nkzd6weztyVPV9PbnxdUrqVs3_oTI,11409 +yapftests/unwrapped_line_test.py,sha256=EVmXcgMRATc468iIWpv3kaW1DyCve-xYJvEeKOj82LE,3218 +yapftests/utils.py,sha256=kbrj8PEnvmrV7kJUEOaIrqOGapkpXWYEoCVEqW2iugM,2708 +yapftests/yapf_test.py,sha256=vSasOEGPHVWNDSwHAZKUhp8V9nkv-ZTPPOtkbJTqcCA,62012 +yapftests/yapf_test_helper.py,sha256=KdxSdP3NKZiqUSba_reXRmW79ECvllFvax3hn7ryCQ4,2825 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/REQUESTED b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/REQUESTED new file mode 100644 index 00000000..e69de29b diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/WHEEL b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/WHEEL new file mode 100644 index 00000000..8b701e93 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.6) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/entry_points.txt b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/entry_points.txt new file mode 100644 index 00000000..a08c5ad0 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/entry_points.txt @@ -0,0 +1,4 @@ +[console_scripts] +yapf = yapf:run_main +yapf-diff = yapf.third_party.yapf_diff.yapf_diff:main + diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/top_level.txt b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/top_level.txt new file mode 100644 index 00000000..63289569 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf-0.31.0.dist-info/top_level.txt @@ -0,0 +1,2 @@ +yapf +yapftests diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/__init__.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/__init__.py new file mode 100644 index 00000000..a70db848 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/__init__.py @@ -0,0 +1,369 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""YAPF. + +YAPF uses the algorithm in clang-format to figure out the "best" formatting for +Python code. It looks at the program as a series of "unwrappable lines" --- +i.e., lines which, if there were no column limit, we would place all tokens on +that line. It then uses a priority queue to figure out what the best formatting +is --- i.e., the formatting with the least penalty. + +It differs from tools like autopep8 and pep8ify in that it doesn't just look for +violations of the style guide, but looks at the module as a whole, making +formatting decisions based on what's the best format for each line. + +If no filenames are specified, YAPF reads the code from stdin. +""" +from __future__ import print_function + +import argparse +import logging +import os +import sys + +from lib2to3.pgen2 import tokenize + +from yapf.yapflib import errors +from yapf.yapflib import file_resources +from yapf.yapflib import py3compat +from yapf.yapflib import style +from yapf.yapflib import yapf_api + +__version__ = '0.31.0' + + +def main(argv): + """Main program. + + Arguments: + argv: command-line arguments, such as sys.argv (including the program name + in argv[0]). + + Returns: + Zero on successful program termination, non-zero otherwise. + With --diff: zero if there were no changes, non-zero otherwise. + + Raises: + YapfError: if none of the supplied files were Python files. + """ + parser = _BuildParser() + args = parser.parse_args(argv[1:]) + if args.version: + print('yapf {}'.format(__version__)) + return 0 + + style_config = args.style + + if args.style_help: + _PrintHelp(args) + return 0 + + if args.lines and len(args.files) > 1: + parser.error('cannot use -l/--lines with more than one file') + + lines = _GetLines(args.lines) if args.lines is not None else None + if not args.files: + # No arguments specified. Read code from stdin. + if args.in_place or args.diff: + parser.error('cannot use --in-place or --diff flags when reading ' + 'from stdin') + + original_source = [] + while True: + if sys.stdin.closed: + break + try: + # Use 'raw_input' instead of 'sys.stdin.read', because otherwise the + # user will need to hit 'Ctrl-D' more than once if they're inputting + # the program by hand. 'raw_input' throws an EOFError exception if + # 'Ctrl-D' is pressed, which makes it easy to bail out of this loop. + original_source.append(py3compat.raw_input()) + except EOFError: + break + except KeyboardInterrupt: + return 1 + + if style_config is None and not args.no_local_style: + style_config = file_resources.GetDefaultStyleForDir(os.getcwd()) + + source = [line.rstrip() for line in original_source] + source[0] = py3compat.removeBOM(source[0]) + + try: + reformatted_source, _ = yapf_api.FormatCode( + py3compat.unicode('\n'.join(source) + '\n'), + filename='', + style_config=style_config, + lines=lines, + verify=args.verify) + except tokenize.TokenError as e: + raise errors.YapfError('%s:%s' % (e.args[1][0], e.args[0])) + + file_resources.WriteReformattedCode('', reformatted_source) + return 0 + + # Get additional exclude patterns from ignorefile + exclude_patterns_from_ignore_file = file_resources.GetExcludePatternsForDir( + os.getcwd()) + + files = file_resources.GetCommandLineFiles(args.files, args.recursive, + (args.exclude or []) + + exclude_patterns_from_ignore_file) + if not files: + raise errors.YapfError('Input filenames did not match any python files') + + changed = FormatFiles( + files, + lines, + style_config=args.style, + no_local_style=args.no_local_style, + in_place=args.in_place, + print_diff=args.diff, + verify=args.verify, + parallel=args.parallel, + quiet=args.quiet, + verbose=args.verbose) + return 1 if changed and (args.diff or args.quiet) else 0 + + +def _PrintHelp(args): + """Prints the help menu.""" + + if args.style is None and not args.no_local_style: + args.style = file_resources.GetDefaultStyleForDir(os.getcwd()) + style.SetGlobalStyle(style.CreateStyleFromConfig(args.style)) + print('[style]') + for option, docstring in sorted(style.Help().items()): + for line in docstring.splitlines(): + print('#', line and ' ' or '', line, sep='') + option_value = style.Get(option) + if isinstance(option_value, set) or isinstance(option_value, list): + option_value = ', '.join(map(str, option_value)) + print(option.lower(), '=', option_value, sep='') + print() + + +def FormatFiles(filenames, + lines, + style_config=None, + no_local_style=False, + in_place=False, + print_diff=False, + verify=False, + parallel=False, + quiet=False, + verbose=False): + """Format a list of files. + + Arguments: + filenames: (list of unicode) A list of files to reformat. + lines: (list of tuples of integers) A list of tuples of lines, [start, end], + that we want to format. The lines are 1-based indexed. This argument + overrides the 'args.lines'. It can be used by third-party code (e.g., + IDEs) when reformatting a snippet of code. + style_config: (string) Style name or file path. + no_local_style: (string) If style_config is None don't search for + directory-local style configuration. + in_place: (bool) Modify the files in place. + print_diff: (bool) Instead of returning the reformatted source, return a + diff that turns the formatted source into reformatter source. + verify: (bool) True if reformatted code should be verified for syntax. + parallel: (bool) True if should format multiple files in parallel. + quiet: (bool) True if should output nothing. + verbose: (bool) True if should print out filenames while processing. + + Returns: + True if the source code changed in any of the files being formatted. + """ + changed = False + if parallel: + import multiprocessing # pylint: disable=g-import-not-at-top + import concurrent.futures # pylint: disable=g-import-not-at-top + workers = min(multiprocessing.cpu_count(), len(filenames)) + with concurrent.futures.ProcessPoolExecutor(workers) as executor: + future_formats = [ + executor.submit(_FormatFile, filename, lines, style_config, + no_local_style, in_place, print_diff, verify, quiet, + verbose) for filename in filenames + ] + for future in concurrent.futures.as_completed(future_formats): + changed |= future.result() + else: + for filename in filenames: + changed |= _FormatFile(filename, lines, style_config, no_local_style, + in_place, print_diff, verify, quiet, verbose) + return changed + + +def _FormatFile(filename, + lines, + style_config=None, + no_local_style=False, + in_place=False, + print_diff=False, + verify=False, + quiet=False, + verbose=False): + """Format an individual file.""" + if verbose and not quiet: + print('Reformatting %s' % filename) + + if style_config is None and not no_local_style: + style_config = file_resources.GetDefaultStyleForDir( + os.path.dirname(filename)) + + try: + reformatted_code, encoding, has_change = yapf_api.FormatFile( + filename, + in_place=in_place, + style_config=style_config, + lines=lines, + print_diff=print_diff, + verify=verify, + logger=logging.warning) + except tokenize.TokenError as e: + raise errors.YapfError('%s:%s:%s' % (filename, e.args[1][0], e.args[0])) + except SyntaxError as e: + e.filename = filename + raise + + if not in_place and not quiet and reformatted_code: + file_resources.WriteReformattedCode(filename, reformatted_code, encoding, + in_place) + return has_change + + +def _GetLines(line_strings): + """Parses the start and end lines from a line string like 'start-end'. + + Arguments: + line_strings: (array of string) A list of strings representing a line + range like 'start-end'. + + Returns: + A list of tuples of the start and end line numbers. + + Raises: + ValueError: If the line string failed to parse or was an invalid line range. + """ + lines = [] + for line_string in line_strings: + # The 'list' here is needed by Python 3. + line = list(map(int, line_string.split('-', 1))) + if line[0] < 1: + raise errors.YapfError('invalid start of line range: %r' % line) + if line[0] > line[1]: + raise errors.YapfError('end comes before start in line range: %r' % line) + lines.append(tuple(line)) + return lines + + +def _BuildParser(): + """Constructs the parser for the command line arguments. + + Returns: + An ArgumentParser instance for the CLI. + """ + parser = argparse.ArgumentParser(description='Formatter for Python code.') + parser.add_argument( + '-v', + '--version', + action='store_true', + help='show version number and exit') + + diff_inplace_quiet_group = parser.add_mutually_exclusive_group() + diff_inplace_quiet_group.add_argument( + '-d', + '--diff', + action='store_true', + help='print the diff for the fixed source') + diff_inplace_quiet_group.add_argument( + '-i', + '--in-place', + action='store_true', + help='make changes to files in place') + diff_inplace_quiet_group.add_argument( + '-q', + '--quiet', + action='store_true', + help='output nothing and set return value') + + lines_recursive_group = parser.add_mutually_exclusive_group() + lines_recursive_group.add_argument( + '-r', + '--recursive', + action='store_true', + help='run recursively over directories') + lines_recursive_group.add_argument( + '-l', + '--lines', + metavar='START-END', + action='append', + default=None, + help='range of lines to reformat, one-based') + + parser.add_argument( + '-e', + '--exclude', + metavar='PATTERN', + action='append', + default=None, + help='patterns for files to exclude from formatting') + parser.add_argument( + '--style', + action='store', + help=('specify formatting style: either a style name (for example "pep8" ' + 'or "google"), or the name of a file with style settings. The ' + 'default is pep8 unless a %s or %s or %s file located in the same ' + 'directory as the source or one of its parent directories ' + '(for stdin, the current directory is used).' % + (style.LOCAL_STYLE, style.SETUP_CONFIG, style.PYPROJECT_TOML))) + parser.add_argument( + '--style-help', + action='store_true', + help=('show style settings and exit; this output can be ' + 'saved to .style.yapf to make your settings ' + 'permanent')) + parser.add_argument( + '--no-local-style', + action='store_true', + help="don't search for local style definition") + parser.add_argument('--verify', action='store_true', help=argparse.SUPPRESS) + parser.add_argument( + '-p', + '--parallel', + action='store_true', + help=('run yapf in parallel when formatting multiple files. Requires ' + 'concurrent.futures in Python 2.X')) + parser.add_argument( + '-vv', + '--verbose', + action='store_true', + help='print out file names while processing') + + parser.add_argument( + 'files', nargs='*', help='reads from stdin when no files are specified.') + return parser + + +def run_main(): # pylint: disable=invalid-name + try: + sys.exit(main(sys.argv)) + except errors.YapfError as e: + sys.stderr.write('yapf: ' + str(e) + '\n') + sys.exit(1) + + +if __name__ == '__main__': + run_main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/__main__.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/__main__.py new file mode 100644 index 00000000..f1d0e322 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/__main__.py @@ -0,0 +1,18 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Main entry point.""" +# pylint: disable=invalid-name +import yapf + +yapf.run_main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..029677e0db5589fb7ebe012b653e8660ae4093de GIT binary patch literal 9693 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 Y0Xb*BAIfFxRM+U$MTW=mgMyay2&BSE%K!iX literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__init__.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__init__.py new file mode 100644 index 00000000..e7522b2c --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90c3959ea0c2320ef0440b22059991cc49950773 GIT binary patch literal 203 zcmYe~<>g`kf(3f>5<{367#@Q-$bb>ZaRB0C79f$r5X_*-=(m!g2qcUkeii6vlaj(WaQ`R2PbFb=jZ5qdb>Kt7bh1b7Ni#G>y@SE zmFeeXCP5V$>sjg-XO^Vu79=KTC#I(s>sKZgq=5;LqWJjCyv&mLc)fzkTO2mI`6;D2 MsdgZjd zy=vfdy7CwQ+gA+Z-_)4?*l7F~zvNFSxZxVyIz7F69v-F9tNFQQ&_ zi>Q~}5-+=D?zoPq92mUvSM#yyR(X{#d}X)`9~!*I>t7kXF6?gYalx(g20w=<4Zg_F zL{2&_7$;6laSf;e>5Kn`I^=hdSiJ4x1(Kd0=5soLCl`?-9mq&G94>N!1q{TY=VdrH{Alacma;d<~A?lzsTX}@L%E%ui(F&yEx}-qhl&3=eU*Jxm9!L zwvaow+Si6{xOK2%Syr&j@tw2KW;aRBMIj7GF+zoQS;>6q32e}>A5acZ2HWQ?hKYMq$f0ynR~IJxz}k~c=}t_?Jb z(`aPn^_@>X*=X%GOWERG(eVdi+JXToJCMYc%%OG*F(7l=aBEzOC@YakM6o;%fv1)v zr;yoXc=H=RuO{-Q{M8y{lM)KUteVT_@mpu^`h{UL+b6w>_^Iu4R8EYpAy=rxRzZL( zMi&Hl#lYrQ(!!`OwI3tQN0%l&fUQWdQ9nuDHU7|e1j?M2PAmfR;qQ0>kd+l=wkD7y z<@cJ7+Pu7ihP;X*JLm0+v^D6p@@R&R){b{)d#&}cx4qTc*hR;OGZK;rAeT@y3kpN| zLz<|lVJ06lMV)gRk}>@@@iKC!s*XX}cga0606v!HN$XC(Wcl2s@o;er|3t<4<4 zlDvSWvg?G~#D(3_iO#yVzqN?3Q?jy&L`5Mb&tZ&4ozQz~PXiZ3Tzn~iOcHbGH8gt4 zP`T*bgUA@XDgbPlOMtFn9>4w)@J6G*AG>cb?>u%X%<-`)-_vMz3tgKKO~Jcvi32-s zC{|YI&@L+k9bQmqJ0$%A+Lat_K9W^vJDkj1qg@2r6=b zZSZsk@M|vtJfCO=?~(1(fASFuZTs5oJu%b5Av^(Ewq`DH9@{hFtWPH`r_Kp*Kdoq| z$t?;H$N$_xZXyH9ACRA53*-*Ri3`Of@`WmAVaQdH(jEn2h$yBLWfiLPe0`j<1|2mS z#R{FW4;jJ;^O<53i>1nEXs0U7QHIUfT(*N08SCC=*L8}sLRvI+vWyxfJBO6FP;SH6 zW~-SWGeIPA4KlJN@7@=CAMLcf-MzKF4f6N9S$#8*NxCik4o#;InvrlZ86Zzlfm>ci z$Fy^D?GOW=BH{KtwE@qY_$Vda#fXG>VN}Shs^%h2|M<-_PkBDz%pCNLQ~DR?<776< zC3US67|s(@-hNH%8jm_Y$_9*dXkoun@3=H*LY+-g!7W$jK`KKT<8|n zQ~;qcQbq{*W-?RiC}aI4R;Y06ay}xL`!01J6(Ta^sv=)uGVY|H*Cv|z+ptLZJjIK- z+ur1&2ZCr9sBUH>vZ&h?F_Y2=N{cjK*2zaI!4Z+BWN<0;59tQyb4so9X(67lQ9!5L zCMd7?qn5%7lj*2I1f;9x|HaPnRIr@fmeoZ0JfEs7N}kb^K?&si@Zh;N$P7VHts}$b zM*}uOC0B^_nRvM7g34LkrL80nAiKC{3d-arF+;}@a%_mmJFShW7_B0?d<~CubZ4kF zr$UT;lSb8WXx`{@I_CqGZ#{-oLJJr*+gvPMf(1})UP7EE|A#hw;G%i_n=`HAe~pJT z)-sb3zJ-;QTdbzInt_i9L9mu<9PaVd=16TWBNV4aofT6)sQbHgndv?Y$mo2@pUE1ifJJXdWXb{(^`&uaogvq33-gk;(Cva09lHy)_hJn!Ma z5A!Ew&%;#*uJa-mkgrm4jS4z9`4cM0?#5+R7UkmzCQ3sNY6IUPtlN)Vj@4^cQ&acl>g- z7R{ySlKQ@1Ey{3!mKk4#5>|YbOpI!{d_hH}PF7so{i3xFg^06R;ocXwlnz=yiqP_X zD&}+{UH^gK7^22=Nqw#6dHEjx-5R|qSfK)M3e?8mfczt&X$fZjPIbRV)8YRIVZ SwQMAQwpFV*wWSDbEdCeh26Juz literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/comment_splicer.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/comment_splicer.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a15d07d51b10dbee3b874a747c04ee8723a02497 GIT binary patch literal 6874 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⪻$0e~yeYP*QQ3jKOz}P=`#j0!?k)Wnly|7SOkYG} ddvr#vn{~_msqvQah4;O><6dl9?y~#x{{Ty^n*IO) literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/continuation_splicer.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/continuation_splicer.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f89ea15fb1c0867045928347d85528cce6a0a6d2 GIT binary patch literal 1437 zcmZ`(&1)Pt6qn{}HfQ| zdzaah6WShn@2S{_9`Y~EwWr*A>Y-5R(~PMdaA(ou>FK?v_kQ}l&DYjK1m8*gTmEN& z&>wbl@pEAF6qeoqK~ah*rcQ-tPU>K*yOlfhQV(>G`ma&y(_jaU2Ft&;g=Wf-^+F26 z#XL7$igh9+WtwndB&qn`r$#;`MllwL;qHWy^}W29>MGZh2Z9||T(EU=F`mqFHD!u$ zP4q+_FxqD_5NZ?O)1+3cjc^;(3)>fHQ7P3d zH<^)BCJJoN&pxZWXG`A(pA*9e(9{-l?U*7$9Uy8zM|IW zBx>BoxrG}46nNV>bnqEkIX}>jt;6O0o~;@H{$DgL3oN4X(s>!SIBb!!FF0~r&n#-z z`UiP6XYIfyU`J;Bt~*_8L$0~dCKm-$cA8S}YnGS5kdCTtP-&xh-G<LqTG2s1~ zpDK;OKkLsKZGA2%JA(W+G`)7Q=gfw_#clX4EBbj*Z_(dPGLbWuOcmEgmQ3m7xh#50 zB|xKz6v<98k+Mp*zxsSD(}l`wrji&)dyv4SpE*5@A0?U__MnDA&tEZ}Eb_YSgmrqa zj-KHvt{3VS0PqPc{V@pSMEFB|9edp`{3r0N_7NU}ypEUmE*awZaV3kq(of>^rpC&S z91N&uS>J8cO|YmtAle(3WVs6m+5>@x(KTgvV}N>)WmFbfmJZJT(E3M?Y-6z%VD4V9 di|FsMH}_h1+3<1y_wnQduxmRr-Y{|^_g@Mmq?UC%^f49?$6G<4m{t?PhD8U$u+t}C+Vp;idtS}w0Lw21eQaFM;SI#PA&8?#U>&G+Z(Fpm z9yx$uT-UJ&+NMW{&b3^gct9H3$kO~Q>iuibA(8%w^c*xxd+&&qqJyUD=oZRbjL&JJz5KUC`Tpxb@qP$}z-Qa?p_z*CsuPcLiNp}Y7)TcJAu#nduo0M>I`Ql{w7r^GJKLP< zA)6d_53714&7cPeEUi~Qc&+4=Q!oS;0Tdtz0{E0;4mkt?;!_TdqWAta><41Vp=P0;V);QyO zot2q->t$WNjk1BaQ8y1#XPMpL)p36MTZdfYukd&8PTjv`q48eg-Ws@)>>>?q+|{;7znQ zL~z&RuC!}SzZ!ahk6IvXuSdZ1ckFv!xT}cB1v_ZCKH6sOd%_D<#qoLWu<42xzDl_- zAvA5h$YLuD_A#{WqMmkz2!uo}+h|>>1_uo%#79bot-AXa8;@D8t&iubj3)PfCf*jF zMLhCvQ0!BQm<_BTba> z&T##R$x_6+R?>RJn08qDK;wp~nc4$`Y5v3;n%te&nEJboGR$(5rygn%Thbn|2ef9c zJI2#T>?0O22s+dLlN)YmJ9gcZp&ir`Nn>*mKI90|dpmw0+)~WMSM2=yu?_0j6Kzt` zGlL@1?o4z*xC^a2V(){2L+IM3_C#;%rMdMdEY8W$5uv2>c%sL8X+CD|6HQED@>h4~ zc7p?VZeM_vpymoWw-i*H2d*E=xkfA84g9&y>TVF!=T?8be7z#8!fCi-u5{P+@6Oe| z?cSg(rSH#4FLW<8oa(-_B(W5yohnott+y&0KaNe(Qc^GBHAEg9p}&D99vhC|5_H4k>}@Qy zOnO-~V~dFR&Vd`BN>;D*4>8tjJT~i|?rRQw&JO;=~6q;`8=UARuY?77q zNtV;achLGwMNpbPjo!YNb9SUd=Zy%u2W``x*Kk2@xnWcIcAvk#)+uds6Or3B$hxO` zv@w#bWAAu4YMXn)t%iYU!3@~;S`h3f_kC3I7#{Ar!=Y3o;ixIs#ZIDC3z%>ByB6%% zo4!{KxLdThFqeiCYscuQ`3e6rnSI?}`=*=I--}o4?IgKeFkH2u>GN4T0Bv#4ldkO^ zG{TnRhNzWLYmbfWr)Y{PNL8Fh5u1B~=c_X)>T#yGvGQ2&)Ja+=&w1tU6Rf{_xl5p1~nPWm(G zH`@6ShU)?Am>+2VqzTj1D)$YQzcsH#=4aPnuwb5!v`#8Yb@P!)CJwc6s1Xy7BjW>2 z*SOv{cbgiF-{4Cbzh50Qeq?GB4hrAE!G8}p_@(0DF4Nk1Zopff>ZHNvE8uhDF>4i) zap4QyNe-?)Vz)J4$BcCM#mIm(GEt^G#Z#Vkq~i^5i}kF?;(C)kX5!sH!1?4G+G8ev zHp+X17V-B=hNsC{(3f%*a30jUH+{tRb+rENV|JK~J453-+F@SJn!&l8#dlVHrK7B( z@o!Of6V3ovG41@r@G5e*<}~YMrQppH%_k4~2XCAjuk_T$aEW`}C{=4a^wDU+E$`u? zmcrnmPWP8CQo|82=YxCcDPL~ef7FdscR1NVMKQFX?r*XeI53fz8{9$|;$1=m{To=a zmy&tP^ngEg1Bu?qZ>Jt?J9YcGh+eGClV!uLdNt4GPn(J@2%vAJ zZLsr{73gtFf;zSw*@Lo4j%8gCz-Zr4GVS>{+K%tK+~o@PG$n2Eg!mna!>k5AJX2FR zgpm{{Wiy03EuI^(E*WQAl3x<%v5-iiD37geEM8x$Y;N6NTLuui4+|yB`OW36_ik1e zH`Z5HZ-}!P7iU&Cls6J&QR4ifTJEMJq$}dAa2;Nu-N$3Qj;u&%2Dm5}Zr;9mYvbMJ z#jVQL#-FdnVCbM8kF6dw0ud(E3}WP4MAEDW4jkZ)8^+eQBNKOLNVg#_P9!oSN znMy!r#KWG3f!LiDsQJ(G%s?Z=M57cBxhhJ?93GW?e zdQS1Ai+T})T1=K$!(>JAAsCj*AL(KN^;lb}(r)@cQqBRszKM^>5buz=BOD#+T<6B8 z=4a<40+H5 z4nW%p+eoAcnmiA#H2oo;G@k5-J<48%xIanZB>TxM*T+~`l#`?T?R|(eT&KTB%-AOD zVz1WJUS~-Zet(b8lGli|Xz`fc6F8nGHt=V?sIiiTfwFhZZRcZ!OZf+$i9_a#5HQR`rA;};H0`vDN?tF`ml%< zKEXU$K%t#7aaFCa)40^%)x|q#IR=;MTBh-+YxyxMArv-5bRHsF@(e^!8p6N#DGcly zA%%+Hix4=bw6nlFZ)t{hRXdzgeT0i{qK`eJkC50D`t;*{p$P-P_EJDO=BGyEuR?tX zE1%U!-P`jp2*PvkCJIdwwh?oXL+K&mKzKWz4}X}1;w9yez9gr#1vF~xyRA4QFds(0 zn2ycGTWc$^zIZFv@y79S75T+!3G421F^73L-4rb(%b8>;DPBeMNr~skEG#Qty6EnO zCKJk7A}B#{LXTKO-!T(NRxg8xWG*8x8tK9&d2=0MvEB=d?GU(%1IZyQ)`R(8(5!kp zI>L6K$R!}MI}2n?czWLuKLMSeAh0oEOi?>rAROFH6J`Y}`&q=~eMK`9nbSDIj~J+= zLbHqSBLw4j{_8{I6ZVPLNk3wW-shnAd1yQ$?f#w+KjS)TUZJl_F#)yued!(VBqdIWtg~N|~au}yw ziUqYIYFH6V<>>UBHu9SVoY(y{wNHlJ>_r002g1wj#t7^7mGisRl_Q26>! z)czuh_W6?@>$!3K#Y>lZuIl19#_>-vO_zETk0i^oL+Oy|emW#%d-|Sn2CDGa`XTui z_7$5$+@2Omj6aC)#2c9VtnI|PtK>~7_jK)_X^h&{h3D*QFg#|Z_T@p`JmTERV8YSZ z*zLeaU$kp=2loCo`PBaCP_Ez^ITR=W5XB(bgY7?I>%$`fQlJo3Axd>Rlz31F^RN9a zJhck>b=sSxOoEbPp~Gk$N-FiGrwk9M8;zh*)CHN{n0aWhdJ(Zqv_Y-6f!_bbqeNCL zh?l8O79qiv*;To!vRr%w2&X&=O0jv*sqc%IXzY0uaeh?}K~J0#j=$r^27Iz0Zjsr^ z_C2%|Z_}*rqbTQ-{FTB)GVwd(J@w)hEF+WrjY3PTmVA)R%Gv&IDhY%&@m*0n!=~RO z`nRZ1yL=0^f5an~P-yxzSwz6Y9Giw8BJgOk^w*|o0zOiosoE{{6wq(6eEJ;90>Myy zQm0Z7#bX(P{>@a@R6#EIj;1E^l(nTJO4R%amJMGfH->6279Ih7arSfltoDg^crHvS z8AciWZG}{Kq=uP6(;o%j}7Ei-9?%g39w=E2!Ul!kfrq%K`ebqOg^Pl zX&nBg$e?Yl7cI4WeKZ3xNirT`a^G3KeW zT1N+hPWKVCO1Zo{ilD>Ho`ty?pl|C_&Z(8s9B!$DG|>qje|KW7X`+j?&ct!5;dr;e z^GN8>zaYlj#cxtXfOluqeU-!_gxfYsjn-DIi*03_)&<2TIJ_U?r7&eXQ%C6SUwUKZ zO9(`3PyO`#tEKOLxSiOBzr1|q&Yym`T|70^vDlK0IwFGmp$f1CDRz8{yCH(-A4Kk@Mo_sG!XfC+~fRkwYb?P45Z26&cU$uZ?H%=)P2bd zY*VP>xkUAbHvBgFe~U+!P-qB7O`U?&l0jBRAzyr1Y{InA-fx?QYFfIWxyO`~b~Xs* zXk`ji)jvZ>1?e9qY!B#+!*-|~pwU;sO$|ZZ{OIwL3Kz}xOCzBzS>%fnNHz&&N`hmB z@E=GjUCHVO0V~+@RW@QL#eBcc^#` zMR|N_dFA?hYgv7$>FxFtI2=Uu8}8|vnb58h4ZuY hJoy561M(lHVNF;Qh3i%Z8vK8`GuF5@Z{@6S|36lsHOK$} literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/format_decision_state.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/format_decision_state.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c426238f4b99ea0b8e9f2cd3387539f98bad8152 GIT binary patch literal 26609 zcmd6QeQaFWb>Dk$-h6U6{18P^A1l4peu-->wcfS8yXtzq6h-dRrYJ=mt#-#=zl`{X z(hSKN^1h+88V{2++Pba3pro!FByLK%hT(Mqw@rh<*r2KZFjAl}g4O|&;vp~`)G)j$ zV5H6dVF-|yV_-h7B!f5b&AV(z=|ex7^ox#ym9?zvCp!NHt?e>+pZU%vlO4C8dM5$S8M=PVhM_m}^(Wf=48 z8*7#IO1&2qEiG%nRD%T1?w1zGFmdiiq2cdlKjHY@%{ zdASmo_NQ{W+4Axgr`cGo)SasDY^cU^#rG?o)2LS*)Gj;C>U!lkqi6s{HyYJ?)2X8K zt_C#}&1(H}E`kKWsR}yxDpSt1b6J%)t~iYqRBrOO&3Ruv4wJD$6CrGhpp zgs|T5Do(YIAyvZ0Q1G3HKjjor_)29D zkeQQFM#w|&6%Wle(7oWgajoub)vKFZ6=%7zaUJt^wvLG;HsS$xpwj?dssNtOaF25g z>*ZD80HbTvAM@08M{U)ejk53Onpad~>oO<-EiMz+=zF=bzRqzYY1g?16pk||1b8~6 zza^62Npyp$T3$oLPUW?YhQe$*m#(8FOxk+G+ghtk<=(=IG$zd;uR(NWCit$2*A+^} z`=GzER&BZ=Vv&&ao7dMWh!nQ!*FaYr70=~VEwjPye+j%ikDvc0f{IZxJ)>lKW+~xW zUIL5E_G~YSXVOb~X*^S2#>?WF4i|GKT+G>UG3Ua?Jm5`vd%UsNO)T@h-Z*Ludi%Ty zJPY1_?*N`d-a+pWp2OaK-eEjPyd$22=csqTcNEV(-UHr)c#e4wc@N{c*L%b}hUd69 z={<_)KJQ)LaXcry$FS^A1bcSDa``VYK2rGdmQq+#;nK&N!Ah=sTxIpkAZpM}h$V+u zl1XE=U7C#e24|^KMw6NVL2*?~V72ZyD`jwo6$g}!l?e*;q`B!P*4Cvhu$Pmd2*+8e zD!=J!AWq6E)NxiNHAy}i2h*973d@bPt@XMtTHji~R8cItMLwjnz!&t|j|QuU!p<1e zHG2o@T&p~Sg&S5_yB_g2U`2OYue{dOR2O!PcMViHZcUh=U0r?y46W|2RjyXnbOnhL z&^lHckqr!0v2>129(O+cDtIOs%Ez{K<+a8&6wxDwHE+;O83^)g_?T}Q z3-$wI6zhJ2%dfwy8KkQU=!-kePwz48rK?|QIc_2B4FfN)10TT7E`4Hj<#lr11r)eP zpV4r39jmjlRbOs$Ym|=I6iCKzhP_uW*TLR(&n_n1<>1TMF&ZGpdC8Qy5YULxE_{=@ z>Qxs)(5V|Cl4OmsfsJaC(bNn8$XNXiaLpAiE#Zw7v<1e-s>@_u(Lcudo59b22|?Se z8EwNg+ZIBrZ6Zu~3~dRM9@A6JH1e$*)@9~oF0)2f!kp9_Xy$hYy~Hi%7CaklCRv8; zW6am9+@7ngijuYMIGq&Pk+^_?4M-W~6(VzEt-LH`)w{5r71daG9wF^M0_j08^hh^j zcqD9oT3y}}X-4yoXh9#l5V5TVG%+b$Hw?88kK5ZPt~AywCsrvU zHNeyT6Q>)?dOA*QT!$=FKe4oYrO{YBG5?|2Y1d!Iep^u|rmj}%S5K@}FNKAkoO&hbLYk4fk#wWC_Nk5QLB_={fz93h2LQ$&M_}YKW-9(Ggt6A4 zxx2-Tsi^WYrz`pg0lBkUK82SiD8B|OuVF20^OvE z>821*BQ1?*2G0zhSZyvu2+w+*t!7UfH%z2tJ%|*Nk_%IE5G{1dK$tSnHo3-H56-MX zYNQOd%aFnicyvqvW;|XCD$7^ukt&ZMNP3kGh{JgiFv4II!K9@~s6hf6 zLjN!hBI8%^^Ept%Dwvt@FCRWfP5!m^-xJ%*q~GWtY!<2yNkPhWE1RxcMhpH?1cseAb9XE&_Y*5o__1Z@eq<$6rhUgU!}K4v z4(x_6-ORla#u;q`U8`0eYezkRR}IR8aZIRC76pK+S6sJ&EMKO;yjQ0z)

J}LZU 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 UbOw21tq1|epO#I{UdYe?Klhjy9smFU literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/identify_container.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/identify_container.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a203d47c696e086604bee3d63a9ff3873c0fb62f GIT binary patch literal 1840 zcmbtUQES{r5Z;w^I^}w2oW?Drgs_D|b5KjrytJkiyGh!Hnrnzd9|S>_wR^seby|6~ zckLZE6r4ZNm*V!#e@U--DE7<^Vt7C0Y=>`|JHF3qe|5*9l~+0CjHg)9!(zD~14VHi4@%1mrdA&?aAW$ZG- z2g?BO^|$QdF~rM;lOi)x6-@kGDs2R3`!iTwMjLi603_0hHp#@uyn^}KVm_6X zG)iX__bomL{w|CMFscm@hMbZUdQ8vgG5MV$%7C9U|Mls_W_gLp3XTiMOhGa>V7&el zL=gbTtffJa$~?`4O?5{fOe}U=kTV$=Qb^9ZgKnEEOe}HmK zUyz67`PzwdOn^oX(&)%H4%$yCr-!b-$H^Ws?wN-+?%W2daTn~{D|XM?TZfMR#qNW- z^?c{VfwL_bK6+pJfJfoz$KvjC4Sic5S9jnIeSdI)VQXxK+S`4y^YjAMxSi^Q97u59 zu7hkObFM|9Te!*1LBq7;U;vyPq+=1^+!N;erm??j`a14?Ep=sfMLNV?=Wgv)A|KWs z^0;m_E|GGUcN*S2Qui!R6QdDl{V|xTJ0J+{(5|yaJ-R_XXM?VTw*ESBJ^KFZ`G;?) zWVqtz?IkL}Hv;m1O7x%0v1{RO4KzOV7H<6xYF!jP6zeGd1xcq#B{gdN87$j}X%&wK zjrrZT}3=3xiDnF77p!8+)mj6)fKK76FNAR_I=>CPiwC4_`wY>?7AObihXYSm&bMHCln%}(}dH6l= z{GAW(d)~k36?P&`bR^$oxDQ2EHd6X(J6M!83mtrf;OJbmKdJ*i1Lm zJKuT3RvMjq?Ja&Bc;4qq7OX7hn$Kn;Wtl95VOEWWoe15DqGMr&&N0g-YR+^bT2U&E$R&cIQx!gDTqF56O0dtQjYf(#qWBYTX*=>qHC9Eo zpfE6*D_qjf)hcuFMLFn1F9ATW?N?1>7n!IUsTftwB;&@MB!JkfUx+t)j_{a&V^{*S z?|GM=^`8f6@WS8mz71?+={@t)#xyXUW#CrA7ydNV57Xwkw_0sYoB9&FH)uEhHt6qa z&Usv~O&j`>_N`6|FPpY?<>|jUUvw&bFN1fzZ*i)NW#e*l*_e9zhvki#KU}ZFL%KN) z^gr#LrMGN63*g&_b-kNb@4){L*Q<0=JL2E_o_Eb9AR#X^E2*Y6fPR`zs4`=Z^tg0P zsmb8%583;fL^V*}i#2&qLA^GREkP+mRi9-taR|6&V%SKloGM&HkB!PK1AS89pBsm8 z#!x&P&$)?np~oV{aZi=X$U6eYnv0sjfYk;r&@Y88HF1nMJJ6*d#1me?Un7#zN^tC_ zuKP-FSg!zGc_!^*9}(gjbD3q%pTpsVRI2!yZueP=5P(wRf`cX-mojxX)F_8H-0Jm@ zANL3GSH0uGUtZQzM^8>K&ie6b@2odCdD(#3OTus!$kAu+B@~$v6-GH~M^!TwGdt04 zrSWHBt41b@syUL{*s6KOvr<&|;-k|?=jZX0FXNMo{!tZD2CFTrEYD(?kL{%TO?>RrBY($_Lj5kRZm9;PmdfB%<7>RwHJg3tgbyz6uGkk`HuP>vjI0$QT(c4?aF~X# zR3Nx)E`6v)pXO}q`9|7&;e(|u{vHmy#Zqcr5J3lWqSQob3-}!XQpL4^-fm%z3xiiO zNeWDmeSOc0@il)Oq$gql8HesV37&Iw4A&=s|JT~kJ{w7pzwRPb0`LSCEvf&=V*H~P zO zyjMHldkXeW_kNLVt)&4er`|p1)bq#0UzZ~4ywD{=IMfLLZ`5MMb97gyg9ZQ

-C; z!sXyPJO4+WNY4nOuFPn2bvgFg2?xuWLY?(o)~cwR0N=nV$I0-)=TCb5`0V0z(EH-_ zG328E_`JQT@4}>NSv3`f(Z9mS@PUMg5*Zv*=s%HST(#(l zfjC?b@6g)=3>SFJJq+Ic-v*(-g9ili-CDoxpR_lsjW|wK634?WVrhp4u(Xz^JJ9`a p5SOre8$KM<+};~!xl`%DYV(s^rDY~QqXW$*hVY%OV5<>*_&+rQB3A$a literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/object_state.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/object_state.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..555e4a47b7e14e2fbf2824e4b9410dec4459fc48 GIT binary patch literal 9343 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 G(*G~LHu10k literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/py3compat.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/py3compat.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c5385ea84be379227d09b150086ce532b115271 GIT binary patch literal 3067 zcmZV=U2ogSahIehik9uz@i}%rnL~k|fQ!_|z+D;yX`IwPxXsBy?BMSB!cyFoMOh+s zyDKX;6rjMlj|cP@6!K&LQL(Rm@?W^8&MYOtc2?Tq&hBt_zK8MRqEBE<>i>?b zD{O&P&q=syPH%^|`R(pn_ls~nYnq)q;T`kb2sijf*LO(hhYN7SCh)t@mf0=fyu|N@ z%Rsf#yVqX{S194DQ+{hxe)q$5_JG}HYe4;gyZ@r%6@M5$f*E90{wRFJzF_MhMerSA zci6@`VH+sNFLt=bHrZV`dCaT>QhRt-|De)ds!}e4b}oWc`@PlLvEwG||Je-Nv* zg;b~YOY~av(gt`5t|FH%f-(XRfF=pLayD>Xg82rf1iuqSx^zs&bPNvt)dm5qX3f%0 zKWAKfJWFzxW=F8&!ipzSJNbZTHAj2xw8yi!&jsEhDgbmj=8HvW<)!#>ZHYz&NAjf13<=e@?>-*&bmnTUA6MWcSgvy(VIm; zRPiT+I601wxNMxpgSG($(NWQ{Sl>}G=c&IYb=9>6r5$FQu? zrnw$uS{zC)qV_OLRGMcuC9AgMV;)V#et|3s8=pPuiD8t)Nr%^8^ztO`$(Qx3v;})x zm;3QYnVxZ7Ql|sX#6#e5^ODM(*YlZ>#PV$M7%;S23Q?%I5G#OxW{7#5pTMai;;y1y z@a)7HlSyd|p1h!xWIw{L%jmHs{?06B_sX9v*zu5dNW|N*HL2iw;$IN8(5+rrlomw5a^~9{rD8} zJyUU-1zDawiDi!8Jx z82pN|WYdZgu$;^6_bNEf@{tj8o;oPthzBUe5m!MB%syl(DpRPmBSbEY%-iCq$n57p z69n>k@KvEg?W#JUr{T@(hH7@t4dU5$khhIE1tWY#mqux}^;BTkHfxL8e)rRsSOY}6 zh5f`jBBhaldZFFoF6|9^v4UFK*KS{)BtmIFiVFHD3d@o!Q|??-(sFI(QhWQ+>%Hdo z`=4sIrqU$2zzn<@pzAxvwc8o{0k1sF4~!fC3Z$mIk_CsZQ{VGwm9Eh>OElo*vn-rf zAWT_BCQy-~(qPJ3XODMtk#G!x6Yw`AB3eaa#0(2h)J^n5iC&1J))4X`&7w$`r>9V% z>YvLk{s?=0m_^cB22TLLHn5t!f+_C;-~@U<2`z5Rb>?8IK&OKu2||{1^-Z3&)1!B> zfRfQn@Wt7{^<2MIK%kz^`VHg~!*dBo09m#ubZM6sB+r9LNt!UlqRQG`tk3wU5%ojhjFhs5!eRAw+OI{T>)5; z#Zv%7n5JTS)UnLYHJ4%`M77@_8Pa1@`2=l6tc~dezL+imgCgW$5fb$=QBaP4flB>P zYZJ_2%CLR*@;&e8Cmf2zY4G|K+Fvdh7f-&A#c|LA96k?3-Zu%-;zwzgVMT%1hy%1p z5f#mvEATr{d$0Guk3JmkJ}b1_#64fCSSX3jQrpnXYnJ#1_w82Rzo9ksAtMZM83Tz# zUlGft4)x)8i;6!34nD-s4q$U19=m{IS+0Gl%TdJgB#MkE0%JgYjld*sbsE;tVgv(J2o;=Q=zQiD?$#?h?P(u5ySn{HjnRGKYyJBY(Y^LdZFN(-~iCgk5 z0LSvE`B_W!KK?9+y41Bi%eOsvIuM7R<2k;e^DWo*%Z^pWUFzBX1N0P7S)R9A{y(Xq B@S6Yt literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/pytree_unwrapper.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/pytree_unwrapper.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea41880f21e21ead016c999cdf83673bd687183f GIT binary patch literal 12915 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 CgXv8G literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/pytree_visitor.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/pytree_visitor.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d478437e50c2f6b90f2c3a86430e0d3c3b5cfc58 GIT binary patch literal 4762 zcmbtYTW=f372aK5MN^83TpF}ZFi?xeEF`jR9$KqyV8>1ZBdK7(hGVcO7Neb^xYBZ$ znHkC^E%(Jn^DA1|kACZK=uhb5zV<0^ea=(Ab7o12z90cYVTZ%Hp7WjWTvl>(vlHO+ zwEs`}uO9`$f9c1?PaQw5;<0zps9+eVP(@id4DnsdqDgI73u&yL)hCT%BMd$ZR6{kN z1gfc(7Po669&O&I@cym#A#|%R~Rvs z&S{g25%uTJXl?tQ&YiIqS$goDM7~XOyE%ew?v&j@!?yQb*W9bBq(z#AQa5I?+qo+n&Tqa#w}51M0Lg-3q{3lMMXL5B7}ix?HSi6BsTRJQstx*Vl$&d~$p6)Xpu*@CELs^( zh(BvLE|e9yoM^2XhX#2WbSYOf9Se9Ew>E zvSMkP3kQl4?TA$9(Nb_rV;{&0!{bOSqT$QLZDt`IZF{0HIPS>E$wV43cyd@|)~_Pc zvH-T{&o$c3;2ozjn`vV8x%87tE0!%i$_tX~aL#g_dg?HlDu}E|WKPsiM{}dAw3&mHlL;K4l5k}>0D5Z0#Q?lkLYEI5be_Xw$bAYk zk-6Iykb|SaQtS$R9G7c|2d4m!U`?hGQRnAyj|`r@FW_tBfPVtZWR|Kux=wtlg(~Q( zu>_28)p3y~1Tn~?cX3!Eq4z2TdQ^EWaMdQZ8c|U?T+Pz6VxNL#6R?0FMr3<{Q?Mf~ z%{xzk=rr(L$764yQQ_0T zg-@fi@EQIdMXq)hoJEf#^D9^Py|eIf7zX){Yn+9ydECO>$7jLQHtoQ82mKA-=af}j zY*rw#BK^e%|BN60`q4qJQ#P3&&X6F(HbHs-J0G#J(i z>T>%<+*czj^Ym(E-Rf*q)(Oe7>CN&yFk3k0+tb0gnCQWYLE0-u+StL3BAIbc8z2P3 zod&l-ts)!T{QQ$^u}zFbZW#0t)=vj;oodmC{VM}xW4$+($%#DDb}*OI5jWK$#JQNw zP?-L7UN#tpD-gkU(FD~k@KCgVqY*cTs*?xk~S$G`W2>!bDC<6T9 zSwyDzs;NQ*{b=#;3ZtbHbN(WD_WcNXt`C_A7%TcHJ$2)~QEIGX-w;*i=a@-xdM)PX z@b0Nj($R&wgvh%*nKmdrN^>G1SSZ9bbL3&(=bs1zEYWHMyn^B4*@IqGwwI!rZD`!9 znM?RG1YX(jQ)E!Ks(FKYRIh!4#}ZUQyAv+nUkA3rWyO>=jEQ6@wmimkLWSnDSD{H< z+=m8x#q9emF+mDKpDqnCysrdK))NuU!gdwW?FHqiX@KNLX5wmn=agbE&@TiLn5@%w8Q#4 z?QZ*$q0u!nP+*{kss0W+4rG6f$aEHg=m8Pk8%8c*t?Nbpa=k@7q=Jib84AG^D^`^k z*u~j(Rh(5d<|^4v(mb7@`a~kqW+W37E1#ZciDh+|W~rNV{ec7Z14-Fqm(rgzMTR7H zB*w-4a}Ob^`+A!4CFM7&CAI49Qm(FwS6_wVJe3-qxNOeMdckd|eDXY?9`S%Qr8tj- zAt}AYzAE;Me1Ex&`BUxdi)&((W_mA6Pmrq)k8x#Rd_3oqAcN0&zTo5Pm1}P6R53$* zKurJ-?Rxj}f>&Nz*6D(Bb4?i3qmUBmaNT3e4sG>^`~{}=j@xaA=BN0T;92_+E$CxE zLUXYQ*7f5C-lV7$4sn$)gv)rKRMzm# z9-hgQCJ0!qo++@L@j53&$Fygbnp%Fr`Iw&_~OzDRS!g@ zM0Tg}g0fC!!_LUfh}#^FmjRmE)qj{SeN*CtG zXv&(M+p_7Sl_ARbn@Lr^pxmsGNOYDh(O^M-NlQ3q5{M^wEbT(VYHW4dwQifi#kF*g zq1W+YtNOQ#uT#5J2==L=7cF8z+4SL+lbz|&K8kPNO6S_IEK;`r==1GIG{og%eX|{P Mqi${c%GUP(0ez-O(*OVf literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/reformatter.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/reformatter.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8fa23cd370d9af1d0672806405fd8ef65e5026e8 GIT binary patch literal 18401 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 F{{fvCceDTi literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/style.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/style.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7fa699ca5224343c421660490f3a678d2b96639d GIT binary patch literal 23363 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 RxS@Zgeyhe~^sg(X{2%7#?5+R+ literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/subtype_assigner.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/subtype_assigner.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a559efc34b1c7bed261f0599caa4e8ab1762d447 GIT binary patch literal 14179 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 literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/unwrapped_line.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/unwrapped_line.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9d70b731ed7f7f25d55ae524914225c4dcdc2e1 GIT binary patch literal 13935 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 jpy+?rpgr;pVW9iBNrz!fx=Q1W!|@eJ*qo zsAS0WfQ#)iiUBEg(nK?%If(<%iIQQ;V+IifaFs#dg#g!EH?6@T;UegdM5K8l0=Azf z(wt$-oD3o!CUj(WKZER{Ze-~Eg<-J)k6H%85M&jZj6ya|mMX>KL!p@zB)%_YBC~79 z%Yd160Iqj!8qFEZA&EXtV7uFL3oi@>8L}`e{4gv-f$wG*J{ggCCaH%ZO`uPRG&#-H z!WC2H=10cMz6Djl`xeNy>h_=n=8bSMiy$7i!E09ieDlHe501QBN=v}p?ZRdIEGn@7 z%>1Zst69`%1ygvM?dv_jMNy-S0&C)8+yb2NbpwE%La=m5dmLhk^;ci?C@$A|bH`g-j#tPU!9 zWl{w#c+0EsT?4pbbrqv0-6vNmKrqL-L*4J3ivVGY&x1YfO&YWckalF2BU-xwJn`Ie z>z4ax_AUi*o(CD|y9RtVE_XgI+MvDxcJ3aSVz>l=ZI1sa0ZSLm?t>Xb#Sd_T8f{Lo zd=CB=t-s9rTQdHBgh~YdDa+ro{N)+{3O)TY4kR8}*~(1zK0Q-<5pByqJL7lhxfy@e z@>gekO3#;k@CA8*g1L~jKZSlDsF7r4gEkG^{Nv*;ZtA6k8`**;D`9>iX@Gcy-|S}B z)_FhQ8$k2Uq0I6nw(yELO}&R-isM z<%pGqV>Eo(FpkXJ%$AO&ft4KLjcmmSFF^2cE%Q4ux^pfKPkXfqdR94nYR^I2( z@8hxYy#(7%RQzmtT{1nAA|G=WQ=_r?imz;CJxXA7i4n`UBqKXUW!dIn?hIKyh2qs9 zdaEy!VGxG>5m<#W5%8gzUxAeax14HzYf+lMD^D467D!Q5Y0P!eU;eXFW5{VBt*X3WZJBAV3d{@FeDypy^#7HzJO|o0;87bu zkaO1cVN5Jz4=>>wUUiz-x7FMP?&`m;W3_Ks?<}vs2x93=Et%j_DsWLFr9;9gx u_OM0czWqZm)ouT=-N9~}>o9g;+BW0eD#z<>lPG0~>v<3w+?D03xB3D+qK}LK literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/yapf_api.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/__pycache__/yapf_api.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8cb60e01e89f5429ec68ff8bdac3a897c4a9b265 GIT binary patch literal 9345 zcmeHNOLH4ncJ3E|MiYF9lBl=bw(PMWQ=lxR;)$Yi4TldG6Ngqr+A8(PgEVm)WRqYw zbZ`*H3$-*;O6__(9t*Q@=#|Jxgy_V4sE{43(+7r4Y_UDKH6X-sEEOZRm7G(1B- zP0z&BY+1Vnub@*It5w`Bc_k?qAlsfT>|5_lymH|cb;AGF0iZY4ZL4uE_)NtOYALn4bRK$ZT1eHSJ*6j zmt9BAtISx_syF?HscB15!nc4&6vB7=I<}p9A|wiaCiMMa_8@_2shdC6Pe=% z&)TsFkP^F$hff1!1uhRzbJtIjFxo_2*Ikyc%V8_HUcEcWc73;rq}rgsLd-@Bh=ijN zH*UHOWU7IPK#gL{M}H#T4Uo6H8%M6sH#@rlMt+w%6-l=h)EjZs3^(t(*HueZcPYdW zIr^6QZsemr=IOg_KiQ&rs8OjoqIQB=3pD4_a^#cB>xw{5QPkX(rn?$Pfg1`}w1Y<2 z3wZT->5OZDaXh4oJ!JVMD< z7zF}@Z-pYEMMygB7FHV)HYnH(xTw1GC^ecZ>&?2q5{b`~SvQE-=d-e7xpRAgyXQv< zO;*jR=F6Snw=hm|x;H{K(x1Xim)C=;n=uoZW1ri>}-r_j*v< ztj)SBi%S^S-c}F|_L@|I);tQ^ZA?7hPnToO1KuAQb`Z7VRxr?uHg-R$v#{C3B5cHQ ztLm;qA_;s(P4FP;@Q7NbRUT*^1}NeVZv?Y>3D=iBP%~;iT} zrbtPj20Uzb2LoB>9c(y_;{mc~16ewW?o(N3M#zuxd$jZVu?VvdYSQfw%6U9?+aBcP-+q>^FO@slu)hSDeKDAjqOW-d^2 zI%KGd5z`qUEtd7m?d~143S~!;sdhKvK~V2Rd)&vyPzRNMS`xOXnX%*fQT8|uC8@WA z$ZsWGBow3uLzohsjilQS>b?-+CVE?LlxV8?uY#wIYXO(|9d3zssOef-;4`VoXA)TC zL;W{;Vx(GHJTxAg2c-l1pq!X#DbOP!v@%p;w*`%QlWB#<+}67W=Wb6)FP_`Me0N$m8#0) zCtDj*K2o`#z>2+AJLbAS){^}Mw#-$B`E^+{YVI}KGda4KEt>1TR-5L!zpqt$ZFY^c zHH_-*mfs-V&aHLRB|ACm?(r}gK?ksl(q3-(jUDnu^7!O{0O}HN!oQ)RFou)l0Zt4j zXQyN;A9s>=Cy@nlEG5u*AUy*7KMiJ`oF(~*>&GUH!5A_OCy4Mwty#CRE%0(Mj%A9(`t3)+!8oDjOjW+2{|O`Ci|=Line8gXx~@+2RCx8 z7Suj1nwpUx0$-^Kt$eb?d5ksTlnD1s?ks@6-oq(`dk!cU)9`6#Bg^@j-|7S}Rqu~b zTCt%K5D3_afrkcYhOE(kb-|CKH~~}=LgoKJ1GQ=)s|*9M%qH_jW-lv9oRK-l-DO4P zS~J~g0HzOq1|+%!UDLRw+UL%Jp6Z{$aXc}Ywx)fpuYRq4ZDdC6R%TJddE#uh-u+{&LX&DTW(J}}^OwWmS!bgmU{#19JN{-M=DL2nDQ{GWUg~~3thKvY`QBy_0TS~MH!+I;#-;6FQO;wT6#HH) zhJP0y)&}KPtL5x;ePJtT>?o)58O90Eo;k-Gme~)mrPM&?sKyqc! Nq;10ilSj_1 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 style.Get('CONTINUATION_INDENT_WIDTH') + + opening = _GetOpeningBracket(current) + if opening: + return not self._ContainerFitsOnStartLine(opening) + + if (current.value not in '{)' and previous.value == '(' and + self._ArgumentListHasDictionaryEntry(current)): + return True + + if style.Get('SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED'): + # Split before arguments in a function call or definition if the + # arguments are terminated by a comma. + opening = _GetOpeningBracket(current) + if opening and opening.previous_token and opening.previous_token.is_name: + if previous.value in '(,': + if opening.matching_bracket.previous_token.value == ',': + return True + + if ((current.is_name or current.value in {'*', '**'}) and + previous.value == ','): + # If we have a function call within an argument list and it won't fit on + # the remaining line, but it will fit on a line by itself, then go ahead + # and split before the call. + opening = _GetOpeningBracket(current) + if (opening and opening.value == '(' and opening.previous_token and + (opening.previous_token.is_name or + opening.previous_token.value in {'*', '**'})): + is_func_call = False + opening = current + while opening: + if opening.value == '(': + is_func_call = True + break + if (not (opening.is_name or opening.value in {'*', '**'}) and + opening.value != '.'): + break + opening = opening.next_token + + if is_func_call: + if (not self._FitsOnLine(current, opening.matching_bracket) or + (opening.matching_bracket.next_token and + opening.matching_bracket.next_token.value != ',' and + not opening.matching_bracket.next_token.ClosesScope())): + return True + + pprevious = previous.previous_token + + # A function call with a dictionary as its first argument may result in + # unreadable formatting if the dictionary spans multiple lines. The + # dictionary itself is formatted just fine, but the remaning arguments are + # indented too far: + # + # function_call({ + # KEY_1: 'value one', + # KEY_2: 'value two', + # }, + # default=False) + if (current.value == '{' and previous.value == '(' and pprevious and + pprevious.is_name): + dict_end = current.matching_bracket + next_token = dict_end.next_token + if next_token.value == ',' and not self._FitsOnLine(current, dict_end): + return True + + if (current.is_name and pprevious and pprevious.is_name and + previous.value == '('): + + if (not self._FitsOnLine(previous, previous.matching_bracket) and + _IsFunctionCallWithArguments(current)): + # There is a function call, with more than 1 argument, where the first + # argument is itself a function call with arguments that does not fit + # into the line. In this specific case, if we split after the first + # argument's opening '(', then the formatting will look bad for the + # rest of the arguments. E.g.: + # + # outer_function_call(inner_function_call( + # inner_arg1, inner_arg2), + # outer_arg1, outer_arg2) + # + # Instead, enforce a split before that argument to keep things looking + # good. + if (style.Get('SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN') or + style.Get('SPLIT_BEFORE_FIRST_ARGUMENT')): + return True + + opening = _GetOpeningBracket(current) + if (opening and opening.value == '(' and opening.previous_token and + (opening.previous_token.is_name or + opening.previous_token.value in {'*', '**'})): + is_func_call = False + opening = current + while opening: + if opening.value == '(': + is_func_call = True + break + if (not (opening.is_name or opening.value in {'*', '**'}) and + opening.value != '.'): + break + opening = opening.next_token + + if is_func_call: + if (not self._FitsOnLine(current, opening.matching_bracket) or + (opening.matching_bracket.next_token and + opening.matching_bracket.next_token.value != ',' and + not opening.matching_bracket.next_token.ClosesScope())): + return True + + if (previous.OpensScope() and not current.OpensScope() and + not current.is_comment and + format_token.Subtype.SUBSCRIPT_BRACKET not in previous.subtypes): + if pprevious and not pprevious.is_keyword and not pprevious.is_name: + # We want to split if there's a comment in the container. + token = current + while token != previous.matching_bracket: + if token.is_comment: + return True + token = token.next_token + if previous.value == '(': + pptoken = previous.previous_token + if not pptoken or not pptoken.is_name: + # Split after the opening of a tuple if it doesn't fit on the current + # line and it's not a function call. + if self._FitsOnLine(previous, previous.matching_bracket): + return False + elif not self._FitsOnLine(previous, previous.matching_bracket): + if len(previous.container_elements) == 1: + return False + + elements = previous.container_elements + [previous.matching_bracket] + i = 1 + while i < len(elements): + if (not elements[i - 1].OpensScope() and + not self._FitsOnLine(elements[i - 1], elements[i])): + return True + i += 1 + + if (self.column_limit - self.column) / float(self.column_limit) < 0.3: + # Try not to squish all of the arguments off to the right. + return True + else: + # Split after the opening of a container if it doesn't fit on the + # current line. + if not self._FitsOnLine(previous, previous.matching_bracket): + return True + + ########################################################################### + # Original Formatting Splitting + # These checks rely upon the original formatting. This is in order to + # attempt to keep hand-written code in the same condition as it was before. + # However, this may cause the formatter to fail to be idempotent. + if (style.Get('SPLIT_BEFORE_BITWISE_OPERATOR') and current.value in '&|' and + previous.lineno < current.lineno): + # Retain the split before a bitwise operator. + return True + + if (current.is_comment and + previous.lineno < current.lineno - current.value.count('\n')): + # If a comment comes in the middle of an unwrapped line (like an if + # conditional with comments interspersed), then we want to split if the + # original comments were on a separate line. + return True + + return False + + def AddTokenToState(self, newline, dry_run, must_split=False): + """Add a token to the format decision state. + + Allow the heuristic to try out adding the token with and without a newline. + Later on, the algorithm will determine which one has the lowest penalty. + + Arguments: + newline: (bool) Add the token on a new line if True. + dry_run: (bool) Don't commit whitespace changes to the FormatToken if + True. + must_split: (bool) A newline was required before this token. + + Returns: + The penalty of splitting after the current token. + """ + self._PushParameterListState(newline) + + penalty = 0 + if newline: + penalty = self._AddTokenOnNewline(dry_run, must_split) + else: + self._AddTokenOnCurrentLine(dry_run) + + penalty += self._CalculateComprehensionState(newline) + penalty += self._CalculateParameterListState(newline) + + return self.MoveStateToNextToken() + penalty + + def _AddTokenOnCurrentLine(self, dry_run): + """Puts the token on the current line. + + Appends the next token to the state and updates information necessary for + indentation. + + Arguments: + dry_run: (bool) Commit whitespace changes to the FormatToken if True. + """ + current = self.next_token + previous = current.previous_token + + spaces = current.spaces_required_before + if isinstance(spaces, list): + # Don't set the value here, as we need to look at the lines near + # this one to determine the actual horizontal alignment value. + spaces = 0 + + if not dry_run: + current.AddWhitespacePrefix(newlines_before=0, spaces=spaces) + + if previous.OpensScope(): + if not current.is_comment: + # Align closing scopes that are on a newline with the opening scope: + # + # foo = [a, + # b, + # ] + self.stack[-1].closing_scope_indent = self.column - 1 + if style.Get('ALIGN_CLOSING_BRACKET_WITH_VISUAL_INDENT'): + self.stack[-1].closing_scope_indent += 1 + self.stack[-1].indent = self.column + spaces + else: + self.stack[-1].closing_scope_indent = ( + self.stack[-1].indent - style.Get('CONTINUATION_INDENT_WIDTH')) + + self.column += spaces + + def _AddTokenOnNewline(self, dry_run, must_split): + """Adds a line break and necessary indentation. + + Appends the next token to the state and updates information necessary for + indentation. + + Arguments: + dry_run: (bool) Don't commit whitespace changes to the FormatToken if + True. + must_split: (bool) A newline was required before this token. + + Returns: + The split penalty for splitting after the current state. + """ + current = self.next_token + previous = current.previous_token + + self.column = self._GetNewlineColumn() + + if not dry_run: + indent_level = self.line.depth + spaces = self.column + if spaces: + spaces -= indent_level * style.Get('INDENT_WIDTH') + current.AddWhitespacePrefix( + newlines_before=1, spaces=spaces, indent_level=indent_level) + + if not current.is_comment: + self.stack[-1].last_space = self.column + self.lowest_level_on_line = self.paren_level + + if (previous.OpensScope() or + (previous.is_comment and previous.previous_token is not None and + previous.previous_token.OpensScope())): + dedent = (style.Get('CONTINUATION_INDENT_WIDTH'), + 0)[style.Get('INDENT_CLOSING_BRACKETS')] + self.stack[-1].closing_scope_indent = ( + max(0, self.stack[-1].indent - dedent)) + self.stack[-1].split_before_closing_bracket = True + + # Calculate the split penalty. + penalty = current.split_penalty + + if must_split: + # Don't penalize for a must split. + return penalty + + if previous.is_pseudo_paren and previous.value == '(': + # Small penalty for splitting after a pseudo paren. + penalty += 50 + + # Add a penalty for each increasing newline we add, but don't penalize for + # splitting before an if-expression or list comprehension. + if current.value not in {'if', 'for'}: + last = self.stack[-1] + last.num_line_splits += 1 + penalty += ( + style.Get('SPLIT_PENALTY_FOR_ADDED_LINE_SPLIT') * + last.num_line_splits) + + if current.OpensScope() and previous.OpensScope(): + # Prefer to keep opening brackets coalesced (unless it's at the beginning + # of a function call). + pprev = previous.previous_token + if not pprev or not pprev.is_name: + penalty += 10 + + return penalty + 10 + + def MoveStateToNextToken(self): + """Calculate format decision state information and move onto the next token. + + Before moving onto the next token, we first calculate the format decision + state given the current token and its formatting decisions. Then the format + decision state is set up so that the next token can be added. + + Returns: + The penalty for the number of characters over the column limit. + """ + current = self.next_token + if not current.OpensScope() and not current.ClosesScope(): + self.lowest_level_on_line = min(self.lowest_level_on_line, + self.paren_level) + + # If we encounter an opening bracket, we add a level to our stack to prepare + # for the subsequent tokens. + if current.OpensScope(): + last = self.stack[-1] + new_indent = style.Get('CONTINUATION_INDENT_WIDTH') + last.last_space + + self.stack.append(_ParenState(new_indent, self.stack[-1].last_space)) + self.paren_level += 1 + + # If we encounter a closing bracket, we can remove a level from our + # parenthesis stack. + if len(self.stack) > 1 and current.ClosesScope(): + if format_token.Subtype.DICTIONARY_KEY_PART in current.subtypes: + self.stack[-2].last_space = self.stack[-2].indent + else: + self.stack[-2].last_space = self.stack[-1].last_space + self.stack.pop() + self.paren_level -= 1 + + is_multiline_string = current.is_string and '\n' in current.value + if is_multiline_string: + # This is a multiline string. Only look at the first line. + self.column += len(current.value.split('\n')[0]) + elif not current.is_pseudo_paren: + self.column += len(current.value) + + self.next_token = self.next_token.next_token + + # Calculate the penalty for overflowing the column limit. + penalty = 0 + if (not current.is_pylint_comment and not current.is_pytype_comment and + not current.is_copybara_comment and self.column > self.column_limit): + excess_characters = self.column - self.column_limit + penalty += style.Get('SPLIT_PENALTY_EXCESS_CHARACTER') * excess_characters + + if is_multiline_string: + # If this is a multiline string, the column is actually the + # end of the last line in the string. + self.column = len(current.value.split('\n')[-1]) + + return penalty + + def _CalculateComprehensionState(self, newline): + """Makes required changes to comprehension state. + + Args: + newline: Whether the current token is to be added on a newline. + + Returns: + The penalty for the token-newline combination given the current + comprehension state. + """ + current = self.next_token + previous = current.previous_token + top_of_stack = self.comp_stack[-1] if self.comp_stack else None + penalty = 0 + + if top_of_stack is not None: + # Check if the token terminates the current comprehension. + if current == top_of_stack.closing_bracket: + last = self.comp_stack.pop() + # Lightly penalize comprehensions that are split across multiple lines. + if last.has_interior_split: + penalty += style.Get('SPLIT_PENALTY_COMPREHENSION') + + return penalty + + if newline: + top_of_stack.has_interior_split = True + + if (format_token.Subtype.COMP_EXPR in current.subtypes and + format_token.Subtype.COMP_EXPR not in previous.subtypes): + self.comp_stack.append(object_state.ComprehensionState(current)) + return penalty + + if (current.value == 'for' and + format_token.Subtype.COMP_FOR in current.subtypes): + if top_of_stack.for_token is not None: + # Treat nested comprehensions like normal comp_if expressions. + # Example: + # my_comp = [ + # a.qux + b.qux + # for a in foo + # --> for b in bar <-- + # if a.zut + b.zut + # ] + if (style.Get('SPLIT_COMPLEX_COMPREHENSION') and + top_of_stack.has_split_at_for != newline and + (top_of_stack.has_split_at_for or + not top_of_stack.HasTrivialExpr())): + penalty += split_penalty.UNBREAKABLE + else: + top_of_stack.for_token = current + top_of_stack.has_split_at_for = newline + + # Try to keep trivial expressions on the same line as the comp_for. + if (style.Get('SPLIT_COMPLEX_COMPREHENSION') and newline and + top_of_stack.HasTrivialExpr()): + penalty += split_penalty.CONNECTED + + if (format_token.Subtype.COMP_IF in current.subtypes and + format_token.Subtype.COMP_IF not in previous.subtypes): + # Penalize breaking at comp_if when it doesn't match the newline structure + # in the rest of the comprehension. + if (style.Get('SPLIT_COMPLEX_COMPREHENSION') and + top_of_stack.has_split_at_for != newline and + (top_of_stack.has_split_at_for or not top_of_stack.HasTrivialExpr())): + penalty += split_penalty.UNBREAKABLE + + return penalty + + def _PushParameterListState(self, newline): + """Push a new parameter list state for a function definition. + + Args: + newline: Whether the current token is to be added on a newline. + """ + current = self.next_token + previous = current.previous_token + + if _IsFunctionDefinition(previous): + first_param_column = previous.total_length + self.stack[-2].indent + self.param_list_stack.append( + object_state.ParameterListState(previous, newline, + first_param_column)) + + def _CalculateParameterListState(self, newline): + """Makes required changes to parameter list state. + + Args: + newline: Whether the current token is to be added on a newline. + + Returns: + The penalty for the token-newline combination given the current + parameter state. + """ + current = self.next_token + previous = current.previous_token + penalty = 0 + + if _IsFunctionDefinition(previous): + first_param_column = previous.total_length + self.stack[-2].indent + if not newline: + param_list = self.param_list_stack[-1] + if param_list.parameters and param_list.has_typed_return: + last_param = param_list.parameters[-1].first_token + last_token = _LastTokenInLine(previous.matching_bracket) + total_length = last_token.total_length + total_length -= last_param.total_length - len(last_param.value) + if total_length + self.column > self.column_limit: + # If we need to split before the trailing code of a function + # definition with return types, then also split before the opening + # parameter so that the trailing bit isn't indented on a line by + # itself: + # + # def rrrrrrrrrrrrrrrrrrrrrr(ccccccccccccccccccccccc: Tuple[Text] + # ) -> List[Tuple[Text, Text]]: + # pass + penalty += split_penalty.VERY_STRONGLY_CONNECTED + return penalty + + if first_param_column <= self.column: + # Make sure we don't split after the opening bracket if the + # continuation indent is greater than the opening bracket: + # + # a( + # b=1, + # c=2) + penalty += split_penalty.VERY_STRONGLY_CONNECTED + return penalty + + if not self.param_list_stack: + return penalty + + param_list = self.param_list_stack[-1] + if current == self.param_list_stack[-1].closing_bracket: + self.param_list_stack.pop() # We're done with this state. + if newline and param_list.has_typed_return: + if param_list.split_before_closing_bracket: + penalty -= split_penalty.STRONGLY_CONNECTED + elif param_list.LastParamFitsOnLine(self.column): + penalty += split_penalty.STRONGLY_CONNECTED + + if (not newline and param_list.has_typed_return and + param_list.has_split_before_first_param): + # Prefer splitting before the closing bracket if there's a return type + # and we've already split before the first parameter. + penalty += split_penalty.STRONGLY_CONNECTED + + return penalty + + if not param_list.parameters: + return penalty + + if newline: + if self._FitsOnLine(param_list.parameters[0].first_token, + _LastTokenInLine(param_list.closing_bracket)): + penalty += split_penalty.STRONGLY_CONNECTED + + if (not newline and style.Get('SPLIT_BEFORE_NAMED_ASSIGNS') and + param_list.has_default_values and + current != param_list.parameters[0].first_token and + current != param_list.closing_bracket and + format_token.Subtype.PARAMETER_START in current.subtypes): + # If we want to split before parameters when there are named assigns, + # then add a penalty for not splitting. + penalty += split_penalty.STRONGLY_CONNECTED + + return penalty + + def _IndentWithContinuationAlignStyle(self, column): + if column == 0: + return column + align_style = style.Get('CONTINUATION_ALIGN_STYLE') + if align_style == 'FIXED': + return ((self.line.depth * style.Get('INDENT_WIDTH')) + + style.Get('CONTINUATION_INDENT_WIDTH')) + if align_style == 'VALIGN-RIGHT': + indent_width = style.Get('INDENT_WIDTH') + return indent_width * int((column + indent_width - 1) / indent_width) + return column + + def _GetNewlineColumn(self): + """Return the new column on the newline.""" + current = self.next_token + previous = current.previous_token + top_of_stack = self.stack[-1] + + if isinstance(current.spaces_required_before, list): + # Don't set the value here, as we need to look at the lines near + # this one to determine the actual horizontal alignment value. + return 0 + elif current.spaces_required_before > 2 or self.line.disable: + return current.spaces_required_before + + cont_aligned_indent = self._IndentWithContinuationAlignStyle( + top_of_stack.indent) + + if current.OpensScope(): + return cont_aligned_indent if self.paren_level else self.first_indent + + if current.ClosesScope(): + if (previous.OpensScope() or + (previous.is_comment and previous.previous_token is not None and + previous.previous_token.OpensScope())): + return max(0, + top_of_stack.indent - style.Get('CONTINUATION_INDENT_WIDTH')) + return top_of_stack.closing_scope_indent + + if (previous and previous.is_string and current.is_string and + format_token.Subtype.DICTIONARY_VALUE in current.subtypes): + return previous.column + + if style.Get('INDENT_DICTIONARY_VALUE'): + if previous and (previous.value == ':' or previous.is_pseudo_paren): + if format_token.Subtype.DICTIONARY_VALUE in current.subtypes: + return top_of_stack.indent + + if (not self.param_list_stack and _IsCompoundStatement(self.line.first) and + (not (style.Get('DEDENT_CLOSING_BRACKETS') or + style.Get('INDENT_CLOSING_BRACKETS')) or + style.Get('SPLIT_BEFORE_FIRST_ARGUMENT'))): + token_indent = ( + len(self.line.first.whitespace_prefix.split('\n')[-1]) + + style.Get('INDENT_WIDTH')) + if token_indent == top_of_stack.indent: + return token_indent + style.Get('CONTINUATION_INDENT_WIDTH') + + if (self.param_list_stack and + not self.param_list_stack[-1].SplitBeforeClosingBracket( + top_of_stack.indent) and top_of_stack.indent + == ((self.line.depth + 1) * style.Get('INDENT_WIDTH'))): + if (format_token.Subtype.PARAMETER_START in current.subtypes or + (previous.is_comment and + format_token.Subtype.PARAMETER_START in previous.subtypes)): + return top_of_stack.indent + style.Get('CONTINUATION_INDENT_WIDTH') + + return cont_aligned_indent + + def _FitsOnLine(self, start, end): + """Determines if line between start and end can fit on the current line.""" + length = end.total_length - start.total_length + if not start.is_pseudo_paren: + length += len(start.value) + return length + self.column <= self.column_limit + + def _EachDictEntryFitsOnOneLine(self, opening): + """Determine if each dict elems can fit on one line.""" + + def PreviousNonCommentToken(tok): + tok = tok.previous_token + while tok.is_comment: + tok = tok.previous_token + return tok + + def ImplicitStringConcatenation(tok): + num_strings = 0 + if tok.is_pseudo_paren: + tok = tok.next_token + while tok.is_string: + num_strings += 1 + tok = tok.next_token + return num_strings > 1 + + def DictValueIsContainer(opening, closing): + """Return true if the dictionary value is a container.""" + if not opening or not closing: + return False + colon = opening.previous_token + while colon: + if not colon.is_pseudo_paren: + break + colon = colon.previous_token + if not colon or colon.value != ':': + return False + key = colon.previous_token + if not key: + return False + return format_token.Subtype.DICTIONARY_KEY_PART in key.subtypes + + closing = opening.matching_bracket + entry_start = opening.next_token + current = opening.next_token.next_token + + while current and current != closing: + if format_token.Subtype.DICTIONARY_KEY in current.subtypes: + prev = PreviousNonCommentToken(current) + if prev.value == ',': + prev = PreviousNonCommentToken(prev.previous_token) + if not DictValueIsContainer(prev.matching_bracket, prev): + length = prev.total_length - entry_start.total_length + length += len(entry_start.value) + if length + self.stack[-2].indent >= self.column_limit: + return False + entry_start = current + if current.OpensScope(): + if ((current.value == '{' or + (current.is_pseudo_paren and current.next_token.value == '{') and + format_token.Subtype.DICTIONARY_VALUE in current.subtypes) or + ImplicitStringConcatenation(current)): + # A dictionary entry that cannot fit on a single line shouldn't matter + # to this calculation. If it can't fit on a single line, then the + # opening should be on the same line as the key and the rest on + # newlines after it. But the other entries should be on single lines + # if possible. + if current.matching_bracket: + current = current.matching_bracket + while current: + if current == closing: + return True + if format_token.Subtype.DICTIONARY_KEY in current.subtypes: + entry_start = current + break + current = current.next_token + else: + current = current.matching_bracket + else: + current = current.next_token + + # At this point, current is the closing bracket. Go back one to get the end + # of the dictionary entry. + current = PreviousNonCommentToken(current) + length = current.total_length - entry_start.total_length + length += len(entry_start.value) + return length + self.stack[-2].indent <= self.column_limit + + def _ArgumentListHasDictionaryEntry(self, token): + """Check if the function argument list has a dictionary as an arg.""" + if _IsArgumentToFunction(token): + while token: + if token.value == '{': + length = token.matching_bracket.total_length - token.total_length + return length + self.stack[-2].indent > self.column_limit + if token.ClosesScope(): + break + if token.OpensScope(): + token = token.matching_bracket + token = token.next_token + return False + + def _ContainerFitsOnStartLine(self, opening): + """Check if the container can fit on its starting line. + + Arguments: + opening: (FormatToken) The unwrapped line we're currently processing. + + Returns: + True if the container fits on the start line. + """ + return (opening.matching_bracket.total_length - opening.total_length + + self.stack[-1].indent) <= self.column_limit + + +_COMPOUND_STMTS = frozenset( + {'for', 'while', 'if', 'elif', 'with', 'except', 'def', 'class'}) + + +def _IsCompoundStatement(token): + if token.value == 'async': + token = token.next_token + return token.value in _COMPOUND_STMTS + + +def _IsFunctionDef(token): + if token.value == 'async': + token = token.next_token + return token.value == 'def' + + +def _IsFunctionCallWithArguments(token): + while token: + if token.value == '(': + token = token.next_token + return token and token.value != ')' + elif token.name not in {'NAME', 'DOT', 'EQUAL'}: + break + token = token.next_token + return False + + +def _IsArgumentToFunction(token): + bracket = unwrapped_line.IsSurroundedByBrackets(token) + if not bracket or bracket.value != '(': + return False + previous = bracket.previous_token + return previous and previous.is_name + + +def _GetOpeningBracket(current): + """Get the opening bracket containing the current token.""" + if current.matching_bracket and not current.is_pseudo_paren: + return current if current.OpensScope() else current.matching_bracket + + while current: + if current.ClosesScope(): + current = current.matching_bracket + elif current.is_pseudo_paren: + current = current.previous_token + elif current.OpensScope(): + return current + current = current.previous_token + return None + + +def _LastTokenInLine(current): + while not current.is_comment and current.next_token: + current = current.next_token + return current + + +def _IsFunctionDefinition(current): + prev = current.previous_token + return (current.value == '(' and prev and + format_token.Subtype.FUNC_DEF in prev.subtypes) + + +def _IsLastScopeInLine(current): + current = current.matching_bracket + while current: + current = current.next_token + if current and current.OpensScope(): + return False + return True + + +def _IsSingleElementTuple(token): + """Check if it's a single-element tuple.""" + close = token.matching_bracket + token = token.next_token + num_commas = 0 + while token != close: + if token.value == ',': + num_commas += 1 + if token.OpensScope(): + token = token.matching_bracket + else: + token = token.next_token + return num_commas == 1 + + +def _ScopeHasNoCommas(token): + """Check if the scope has no commas.""" + close = token.matching_bracket + token = token.next_token + while token != close: + if token.value == ',': + return False + if token.OpensScope(): + token = token.matching_bracket + else: + token = token.next_token + return True + + +class _ParenState(object): + """Maintains the state of the bracket enclosures. + + A stack of _ParenState objects are kept so that we know how to indent relative + to the brackets. + + Attributes: + indent: The column position to which a specified parenthesis level needs to + be indented. + last_space: The column position of the last space on each level. + closing_scope_indent: The column position of the closing indentation. + split_before_closing_bracket: Whether a newline needs to be inserted before + the closing bracket. We only want to insert a newline before the closing + bracket if there also was a newline after the beginning left bracket. + num_line_splits: Number of line splits this _ParenState contains already. + Each subsequent line split gets an increasing penalty. + """ + + # TODO(morbo): This doesn't track "bin packing." + + def __init__(self, indent, last_space): + self.indent = indent + self.last_space = last_space + self.closing_scope_indent = 0 + self.split_before_closing_bracket = False + self.num_line_splits = 0 + + def Clone(self): + state = _ParenState(self.indent, self.last_space) + state.closing_scope_indent = self.closing_scope_indent + state.split_before_closing_bracket = self.split_before_closing_bracket + state.num_line_splits = self.num_line_splits + return state + + def __repr__(self): + return '[indent::%d, last_space::%d, closing_scope_indent::%d]' % ( + self.indent, self.last_space, self.closing_scope_indent) + + def __eq__(self, other): + return hash(self) == hash(other) + + def __ne__(self, other): + return not self == other + + def __hash__(self, *args, **kwargs): + return hash((self.indent, self.last_space, self.closing_scope_indent, + self.split_before_closing_bracket, self.num_line_splits)) diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/format_token.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/format_token.py new file mode 100644 index 00000000..92c26ee5 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/format_token.py @@ -0,0 +1,385 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Pytree nodes with extra formatting information. + +This is a thin wrapper around a pytree.Leaf node. +""" + +import keyword +import re + +from lib2to3.pgen2 import token + +from yapf.yapflib import py3compat +from yapf.yapflib import pytree_utils +from yapf.yapflib import style + +CONTINUATION = token.N_TOKENS + + +class Subtype(object): + """Subtype information about tokens. + + Gleaned from parsing the code. Helps determine the best formatting. + """ + NONE = 0 + UNARY_OPERATOR = 1 + BINARY_OPERATOR = 2 + A_EXPR_OPERATOR = 3 + M_EXPR_OPERATOR = 4 + SUBSCRIPT_COLON = 5 + SUBSCRIPT_BRACKET = 6 + DEFAULT_OR_NAMED_ASSIGN = 7 + DEFAULT_OR_NAMED_ASSIGN_ARG_LIST = 8 + VARARGS_LIST = 9 + VARARGS_STAR = 10 + KWARGS_STAR_STAR = 11 + ASSIGN_OPERATOR = 12 + DICTIONARY_KEY = 13 + DICTIONARY_KEY_PART = 14 + DICTIONARY_VALUE = 15 + DICT_SET_GENERATOR = 16 + COMP_EXPR = 17 + COMP_FOR = 18 + COMP_IF = 19 + FUNC_DEF = 20 + DECORATOR = 21 + TYPED_NAME = 22 + TYPED_NAME_ARG_LIST = 23 + SIMPLE_EXPRESSION = 24 + PARAMETER_START = 25 + PARAMETER_STOP = 26 + + +def _TabbedContinuationAlignPadding(spaces, align_style, tab_width): + """Build padding string for continuation alignment in tabbed indentation. + + Arguments: + spaces: (int) The number of spaces to place before the token for alignment. + align_style: (str) The alignment style for continuation lines. + tab_width: (int) Number of columns of each tab character. + + Returns: + A padding string for alignment with style specified by align_style option. + """ + if align_style in ('FIXED', 'VALIGN-RIGHT'): + if spaces > 0: + return '\t' * int((spaces + tab_width - 1) / tab_width) + return '' + return ' ' * spaces + + +class FormatToken(object): + """A wrapper around pytree Leaf nodes. + + This represents the token plus additional information useful for reformatting + the code. + + Attributes: + node: The PyTree node this token represents. + next_token: The token in the unwrapped line after this token or None if this + is the last token in the unwrapped line. + previous_token: The token in the unwrapped line before this token or None if + this is the first token in the unwrapped line. + matching_bracket: If a bracket token ('[', '{', or '(') the matching + bracket. + parameters: If this and its following tokens make up a parameter list, then + this is a list of those parameters. + container_opening: If the object is in a container, this points to its + opening bracket. + container_elements: If this is the start of a container, a list of the + elements in the container. + whitespace_prefix: The prefix for the whitespace. + spaces_required_before: The number of spaces required before a token. This + is a lower-bound for the formatter and not a hard requirement. For + instance, a comment may have n required spaces before it. But the + formatter won't place n spaces before all comments. Only those that are + moved to the end of a line of code. The formatter may use different + spacing when appropriate. + can_break_before: True if we're allowed to break before this token. + must_break_before: True if we're required to break before this token. + total_length: The total length of the unwrapped line up to and including + whitespace and this token. However, this doesn't include the initial + indentation amount. + split_penalty: The penalty for splitting the line before this token. + """ + + def __init__(self, node): + """Constructor. + + Arguments: + node: (pytree.Leaf) The node that's being wrapped. + """ + self.node = node + self.next_token = None + self.previous_token = None + self.matching_bracket = None + self.parameters = [] + self.container_opening = None + self.container_elements = [] + self.whitespace_prefix = '' + self.can_break_before = False + self.must_break_before = False + self.total_length = 0 # TODO(morbo): Think up a better name. + self.split_penalty = 0 + + if self.is_comment: + self.spaces_required_before = style.Get('SPACES_BEFORE_COMMENT') + else: + self.spaces_required_before = 0 + + if self.is_continuation: + self.value = self.node.value.rstrip() + else: + self.value = self.node.value + + @property + def formatted_whitespace_prefix(self): + if style.Get('INDENT_BLANK_LINES'): + without_newlines = self.whitespace_prefix.lstrip('\n') + height = len(self.whitespace_prefix) - len(without_newlines) + if height: + return ('\n' + without_newlines) * height + return self.whitespace_prefix + + def AddWhitespacePrefix(self, newlines_before, spaces=0, indent_level=0): + """Register a token's whitespace prefix. + + This is the whitespace that will be output before a token's string. + + Arguments: + newlines_before: (int) The number of newlines to place before the token. + spaces: (int) The number of spaces to place before the token. + indent_level: (int) The indentation level. + """ + if style.Get('USE_TABS'): + if newlines_before > 0: + indent_before = '\t' * indent_level + _TabbedContinuationAlignPadding( + spaces, style.Get('CONTINUATION_ALIGN_STYLE'), + style.Get('INDENT_WIDTH')) + else: + indent_before = '\t' * indent_level + ' ' * spaces + else: + indent_before = (' ' * indent_level * style.Get('INDENT_WIDTH') + + ' ' * spaces) + + if self.is_comment: + comment_lines = [s.lstrip() for s in self.value.splitlines()] + self.node.value = ('\n' + indent_before).join(comment_lines) + + # Update our own value since we are changing node value + self.value = self.node.value + + if not self.whitespace_prefix: + self.whitespace_prefix = ('\n' * (self.newlines or newlines_before) + + indent_before) + else: + self.whitespace_prefix += indent_before + + def AdjustNewlinesBefore(self, newlines_before): + """Change the number of newlines before this token.""" + self.whitespace_prefix = ('\n' * newlines_before + + self.whitespace_prefix.lstrip('\n')) + + def RetainHorizontalSpacing(self, first_column, depth): + """Retains a token's horizontal spacing.""" + previous = self.previous_token + if not previous: + return + + if previous.is_pseudo_paren: + previous = previous.previous_token + if not previous: + return + + cur_lineno = self.lineno + prev_lineno = previous.lineno + if previous.is_multiline_string: + prev_lineno += previous.value.count('\n') + + if (cur_lineno != prev_lineno or + (previous.is_pseudo_paren and previous.value != ')' and + cur_lineno != previous.previous_token.lineno)): + self.spaces_required_before = ( + self.column - first_column + depth * style.Get('INDENT_WIDTH')) + return + + cur_column = self.node.column + prev_column = previous.node.column + prev_len = len(previous.value) + + if previous.is_pseudo_paren and previous.value == ')': + prev_column -= 1 + prev_len = 0 + + if previous.is_multiline_string: + prev_len = len(previous.value.split('\n')[-1]) + if '\n' in previous.value: + prev_column = 0 # Last line starts in column 0. + + self.spaces_required_before = cur_column - (prev_column + prev_len) + + def OpensScope(self): + return self.value in pytree_utils.OPENING_BRACKETS + + def ClosesScope(self): + return self.value in pytree_utils.CLOSING_BRACKETS + + def __repr__(self): + msg = 'FormatToken(name={0}, value={1}, lineno={2}'.format( + self.name, self.value, self.lineno) + msg += ', pseudo)' if self.is_pseudo_paren else ')' + return msg + + @property + @py3compat.lru_cache() + def node_split_penalty(self): + """Split penalty attached to the pytree node of this token.""" + return pytree_utils.GetNodeAnnotation( + self.node, pytree_utils.Annotation.SPLIT_PENALTY, default=0) + + @property + def newlines(self): + """The number of newlines needed before this token.""" + return pytree_utils.GetNodeAnnotation(self.node, + pytree_utils.Annotation.NEWLINES) + + @property + def must_split(self): + """Return true if the token requires a split before it.""" + return pytree_utils.GetNodeAnnotation(self.node, + pytree_utils.Annotation.MUST_SPLIT) + + @property + def column(self): + """The original column number of the node in the source.""" + return self.node.column + + @property + def lineno(self): + """The original line number of the node in the source.""" + return self.node.lineno + + @property + @py3compat.lru_cache() + def subtypes(self): + """Extra type information for directing formatting.""" + value = pytree_utils.GetNodeAnnotation(self.node, + pytree_utils.Annotation.SUBTYPE) + return [Subtype.NONE] if value is None else value + + @property + @py3compat.lru_cache() + def is_binary_op(self): + """Token is a binary operator.""" + return Subtype.BINARY_OPERATOR in self.subtypes + + @property + @py3compat.lru_cache() + def is_a_expr_op(self): + """Token is an a_expr operator.""" + return Subtype.A_EXPR_OPERATOR in self.subtypes + + @property + @py3compat.lru_cache() + def is_m_expr_op(self): + """Token is an m_expr operator.""" + return Subtype.M_EXPR_OPERATOR in self.subtypes + + @property + @py3compat.lru_cache() + def is_arithmetic_op(self): + """Token is an arithmetic operator.""" + return self.is_a_expr_op or self.is_m_expr_op + + @property + @py3compat.lru_cache() + def is_simple_expr(self): + """Token is an operator in a simple expression.""" + return Subtype.SIMPLE_EXPRESSION in self.subtypes + + @property + @py3compat.lru_cache() + def is_subscript_colon(self): + """Token is a subscript colon.""" + return Subtype.SUBSCRIPT_COLON in self.subtypes + + @property + @py3compat.lru_cache() + def name(self): + """A string representation of the node's name.""" + return pytree_utils.NodeName(self.node) + + @property + def is_comment(self): + return self.node.type == token.COMMENT + + @property + def is_continuation(self): + return self.node.type == CONTINUATION + + @property + @py3compat.lru_cache() + def is_keyword(self): + return keyword.iskeyword(self.value) + + @property + @py3compat.lru_cache() + def is_name(self): + return self.node.type == token.NAME and not self.is_keyword + + @property + def is_number(self): + return self.node.type == token.NUMBER + + @property + def is_string(self): + return self.node.type == token.STRING + + @property + @py3compat.lru_cache() + def is_multiline_string(self): + """Test if this string is a multiline string. + + Returns: + A multiline string always ends with triple quotes, so if it is a string + token, inspect the last 3 characters and return True if it is a triple + double or triple single quote mark. + """ + return self.is_string and self.value.endswith(('"""', "'''")) + + @property + @py3compat.lru_cache() + def is_docstring(self): + return self.is_multiline_string and not self.node.prev_sibling + + @property + @py3compat.lru_cache() + def is_pseudo_paren(self): + return hasattr(self.node, 'is_pseudo') and self.node.is_pseudo + + @property + def is_pylint_comment(self): + return self.is_comment and re.match(r'#.*\bpylint:\s*(disable|enable)=', + self.value) + + @property + def is_pytype_comment(self): + return self.is_comment and re.match(r'#.*\bpytype:\s*(disable|enable)=', + self.value) + + @property + def is_copybara_comment(self): + return self.is_comment and re.match(r'#.*\bcopybara:(strip|insert|replace)', + self.value) diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/identify_container.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/identify_container.py new file mode 100644 index 00000000..5c5fc5bf --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/identify_container.py @@ -0,0 +1,67 @@ +# Copyright 2018 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Identify containers for lib2to3 trees. + +This module identifies containers and the elements in them. Each element points +to the opening bracket and vice-versa. + + IdentifyContainers(): the main function exported by this module. +""" + +from yapf.yapflib import pytree_utils +from yapf.yapflib import pytree_visitor + + +def IdentifyContainers(tree): + """Run the identify containers visitor over the tree, modifying it in place. + + Arguments: + tree: the top-level pytree node to annotate with subtypes. + """ + identify_containers = _IdentifyContainers() + identify_containers.Visit(tree) + + +class _IdentifyContainers(pytree_visitor.PyTreeVisitor): + """_IdentifyContainers - see file-level docstring for detailed description.""" + + def Visit_trailer(self, node): # pylint: disable=invalid-name + for child in node.children: + self.Visit(child) + + if len(node.children) != 3: + return + if pytree_utils.NodeName(node.children[0]) != 'LPAR': + return + + if pytree_utils.NodeName(node.children[1]) == 'arglist': + for child in node.children[1].children: + pytree_utils.SetOpeningBracket( + pytree_utils.FirstLeafNode(child), node.children[0]) + else: + pytree_utils.SetOpeningBracket( + pytree_utils.FirstLeafNode(node.children[1]), node.children[0]) + + def Visit_atom(self, node): # pylint: disable=invalid-name + for child in node.children: + self.Visit(child) + + if len(node.children) != 3: + return + if pytree_utils.NodeName(node.children[0]) != 'LPAR': + return + + for child in node.children[1].children: + pytree_utils.SetOpeningBracket( + pytree_utils.FirstLeafNode(child), node.children[0]) diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/line_joiner.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/line_joiner.py new file mode 100644 index 00000000..84346c26 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/line_joiner.py @@ -0,0 +1,109 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Join unwrapped lines together. + +Determine how many lines can be joined into one line. For instance, we could +join these statements into one line: + + if a == 42: + continue + +like this: + + if a == 42: continue + +There are a few restrictions: + + 1. The lines should have been joined in the original source. + 2. The joined lines must not go over the column boundary if placed on the same + line. + 3. They need to be very simple statements. + +Note: Because we don't allow the use of a semicolon to separate statements, it +follows that there can only be at most two lines to join. +""" + +from yapf.yapflib import style + +_CLASS_OR_FUNC = frozenset({'def', 'class'}) + + +def CanMergeMultipleLines(lines, last_was_merged=False): + """Determine if multiple lines can be joined into one. + + Arguments: + lines: (list of UnwrappedLine) This is a splice of UnwrappedLines from the + full code base. + last_was_merged: (bool) The last line was merged. + + Returns: + True if two consecutive lines can be joined together. In reality, this will + only happen if two consecutive lines can be joined, due to the style guide. + """ + # The indentation amount for the starting line (number of spaces). + indent_amt = lines[0].depth * style.Get('INDENT_WIDTH') + if len(lines) == 1 or indent_amt > style.Get('COLUMN_LIMIT'): + return False + + if (len(lines) >= 3 and lines[2].depth >= lines[1].depth and + lines[0].depth != lines[2].depth): + # If lines[2]'s depth is greater than or equal to line[1]'s depth, we're not + # looking at a single statement (e.g., if-then, while, etc.). A following + # line with the same depth as the first line isn't part of the lines we + # would want to combine. + return False # Don't merge more than two lines together. + + if lines[0].first.value in _CLASS_OR_FUNC: + # Don't join lines onto the starting line of a class or function. + return False + + limit = style.Get('COLUMN_LIMIT') - indent_amt + if lines[0].last.total_length < limit: + limit -= lines[0].last.total_length + + if lines[0].first.value == 'if': + return _CanMergeLineIntoIfStatement(lines, limit) + if last_was_merged and lines[0].first.value in {'elif', 'else'}: + return _CanMergeLineIntoIfStatement(lines, limit) + + # TODO(morbo): Other control statements? + + return False + + +def _CanMergeLineIntoIfStatement(lines, limit): + """Determine if we can merge a short if-then statement into one line. + + Two lines of an if-then statement can be merged if they were that way in the + original source, fit on the line without going over the column limit, and are + considered "simple" statements --- typically statements like 'pass', + 'continue', and 'break'. + + Arguments: + lines: (list of UnwrappedLine) The lines we are wanting to merge. + limit: (int) The amount of space remaining on the line. + + Returns: + True if the lines can be merged, False otherwise. + """ + if len(lines[1].tokens) == 1 and lines[1].last.is_multiline_string: + # This might be part of a multiline shebang. + return True + if lines[0].lineno != lines[1].lineno: + # Don't merge lines if the original lines weren't merged. + return False + if lines[1].last.total_length >= limit: + # Don't merge lines if the result goes over the column limit. + return False + return style.Get('JOIN_MULTIPLE_LINES') diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/object_state.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/object_state.py new file mode 100644 index 00000000..4ae8eaeb --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/object_state.py @@ -0,0 +1,235 @@ +# Copyright 2017 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Represents the state of Python objects being formatted. + +Objects (e.g., list comprehensions, dictionaries, etc.) have specific +requirements on how they're formatted. These state objects keep track of these +requirements. +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from yapf.yapflib import format_token +from yapf.yapflib import py3compat +from yapf.yapflib import style + + +class ComprehensionState(object): + """Maintains the state of list comprehension formatting decisions. + + A stack of ComprehensionState objects are kept to ensure that list + comprehensions are wrapped with well-defined rules. + + Attributes: + expr_token: The first token in the comprehension. + for_token: The first 'for' token of the comprehension. + opening_bracket: The opening bracket of the list comprehension. + closing_bracket: The closing bracket of the list comprehension. + has_split_at_for: Whether there is a newline immediately before the + for_token. + has_interior_split: Whether there is a newline within the comprehension. + That is, a split somewhere after expr_token or before closing_bracket. + """ + + def __init__(self, expr_token): + self.expr_token = expr_token + self.for_token = None + self.has_split_at_for = False + self.has_interior_split = False + + def HasTrivialExpr(self): + """Returns whether the comp_expr is "trivial" i.e. is a single token.""" + return self.expr_token.next_token.value == 'for' + + @property + def opening_bracket(self): + return self.expr_token.previous_token + + @property + def closing_bracket(self): + return self.opening_bracket.matching_bracket + + def Clone(self): + clone = ComprehensionState(self.expr_token) + clone.for_token = self.for_token + clone.has_split_at_for = self.has_split_at_for + clone.has_interior_split = self.has_interior_split + return clone + + def __repr__(self): + return ('[opening_bracket::%s, for_token::%s, has_split_at_for::%s,' + ' has_interior_split::%s, has_trivial_expr::%s]' % + (self.opening_bracket, self.for_token, self.has_split_at_for, + self.has_interior_split, self.HasTrivialExpr())) + + def __eq__(self, other): + return hash(self) == hash(other) + + def __ne__(self, other): + return not self == other + + def __hash__(self, *args, **kwargs): + return hash((self.expr_token, self.for_token, self.has_split_at_for, + self.has_interior_split)) + + +class ParameterListState(object): + """Maintains the state of function parameter list formatting decisions. + + Attributes: + opening_bracket: The opening bracket of the parameter list. + closing_bracket: The closing bracket of the parameter list. + has_typed_return: True if the function definition has a typed return. + ends_in_comma: True if the parameter list ends in a comma. + last_token: Returns the last token of the function declaration. + has_default_values: True if the parameters have default values. + has_split_before_first_param: Whether there is a newline before the first + parameter. + opening_column: The position of the opening parameter before a newline. + parameters: A list of parameter objects (Parameter). + split_before_closing_bracket: Split before the closing bracket. Sometimes + needed if the indentation would collide. + """ + + def __init__(self, opening_bracket, newline, opening_column): + self.opening_bracket = opening_bracket + self.has_split_before_first_param = newline + self.opening_column = opening_column + self.parameters = opening_bracket.parameters + self.split_before_closing_bracket = False + + @property + def closing_bracket(self): + return self.opening_bracket.matching_bracket + + @property + def has_typed_return(self): + return self.closing_bracket.next_token.value == '->' + + @property + @py3compat.lru_cache() + def has_default_values(self): + return any(param.has_default_value for param in self.parameters) + + @property + @py3compat.lru_cache() + def ends_in_comma(self): + if not self.parameters: + return False + return self.parameters[-1].last_token.next_token.value == ',' + + @property + @py3compat.lru_cache() + def last_token(self): + token = self.opening_bracket.matching_bracket + while not token.is_comment and token.next_token: + token = token.next_token + return token + + @py3compat.lru_cache() + def LastParamFitsOnLine(self, indent): + """Return true if the last parameter fits on a single line.""" + if not self.has_typed_return: + return False + if not self.parameters: + return True + total_length = self.last_token.total_length + last_param = self.parameters[-1].first_token + total_length -= last_param.total_length - len(last_param.value) + return total_length + indent <= style.Get('COLUMN_LIMIT') + + @py3compat.lru_cache() + def SplitBeforeClosingBracket(self, indent): + """Return true if there's a split before the closing bracket.""" + if style.Get('DEDENT_CLOSING_BRACKETS'): + return True + if self.ends_in_comma: + return True + if not self.parameters: + return False + total_length = self.last_token.total_length + last_param = self.parameters[-1].first_token + total_length -= last_param.total_length - len(last_param.value) + return total_length + indent > style.Get('COLUMN_LIMIT') + + def Clone(self): + clone = ParameterListState(self.opening_bracket, + self.has_split_before_first_param, + self.opening_column) + clone.split_before_closing_bracket = self.split_before_closing_bracket + clone.parameters = [param.Clone() for param in self.parameters] + return clone + + def __repr__(self): + return ('[opening_bracket::%s, has_split_before_first_param::%s, ' + 'opening_column::%d]' % + (self.opening_bracket, self.has_split_before_first_param, + self.opening_column)) + + def __eq__(self, other): + return hash(self) == hash(other) + + def __ne__(self, other): + return not self == other + + def __hash__(self, *args, **kwargs): + return hash( + (self.opening_bracket, self.has_split_before_first_param, + self.opening_column, (hash(param) for param in self.parameters))) + + +class Parameter(object): + """A parameter in a parameter list. + + Attributes: + first_token: (format_token.FormatToken) First token of parameter. + last_token: (format_token.FormatToken) Last token of parameter. + has_default_value: (boolean) True if the parameter has a default value + """ + + def __init__(self, first_token, last_token): + self.first_token = first_token + self.last_token = last_token + + @property + @py3compat.lru_cache() + def has_default_value(self): + """Returns true if the parameter has a default value.""" + tok = self.first_token + while tok != self.last_token: + if format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN in tok.subtypes: + return True + if tok.OpensScope(): + tok = tok.matching_bracket + else: + tok = tok.next_token + return False + + def Clone(self): + return Parameter(self.first_token, self.last_token) + + def __repr__(self): + return '[first_token::%s, last_token:%s]' % (self.first_token, + self.last_token) + + def __eq__(self, other): + return hash(self) == hash(other) + + def __ne__(self, other): + return not self == other + + def __hash__(self, *args, **kwargs): + return hash((self.first_token, self.last_token)) diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/py3compat.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/py3compat.py new file mode 100644 index 00000000..7c905237 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/py3compat.py @@ -0,0 +1,131 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Utilities for Python2 / Python3 compatibility.""" + +import codecs +import io +import os +import sys + +PY3 = sys.version_info[0] >= 3 +PY36 = sys.version_info[0] >= 3 and sys.version_info[1] >= 6 +PY37 = sys.version_info[0] >= 3 and sys.version_info[1] >= 7 +PY38 = sys.version_info[0] >= 3 and sys.version_info[1] >= 8 + +if PY3: + StringIO = io.StringIO + BytesIO = io.BytesIO + + import codecs + + def open_with_encoding(filename, mode, encoding, newline=''): # pylint: disable=unused-argument + return codecs.open(filename, mode=mode, encoding=encoding) + + import functools + lru_cache = functools.lru_cache + + range = range + ifilter = filter + + def raw_input(): + wrapper = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8') + return wrapper.buffer.raw.readall().decode('utf-8') + + import configparser + + # Mappings from strings to booleans (such as '1' to True, 'false' to False, + # etc.) + CONFIGPARSER_BOOLEAN_STATES = configparser.ConfigParser.BOOLEAN_STATES +else: + import __builtin__ + import cStringIO + StringIO = BytesIO = cStringIO.StringIO + + open_with_encoding = io.open + + # Python 2.7 doesn't have a native LRU cache, so do nothing. + def lru_cache(maxsize=128, typed=False): + + def fake_wrapper(user_function): + return user_function + + return fake_wrapper + + range = xrange + + from itertools import ifilter + raw_input = raw_input + + import ConfigParser as configparser + CONFIGPARSER_BOOLEAN_STATES = configparser.ConfigParser._boolean_states # pylint: disable=protected-access + + +def EncodeAndWriteToStdout(s, encoding='utf-8'): + """Encode the given string and emit to stdout. + + The string may contain non-ascii characters. This is a problem when stdout is + redirected, because then Python doesn't know the encoding and we may get a + UnicodeEncodeError. + + Arguments: + s: (string) The string to encode. + encoding: (string) The encoding of the string. + """ + if PY3: + sys.stdout.buffer.write(s.encode(encoding)) + elif sys.platform == 'win32': + # On python 2 and Windows universal newline transformation will be in + # effect on stdout. Python 2 will not let us avoid the easily because + # it happens based on whether the file handle is opened in O_BINARY or + # O_TEXT state. However we can tell Windows itself to change the current + # mode, and python 2 will follow suit. However we must take care to change + # the mode on the actual external stdout not just the current sys.stdout + # which may have been monkey-patched inside the python environment. + import msvcrt # pylint: disable=g-import-not-at-top + if sys.__stdout__ is sys.stdout: + msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) + sys.stdout.write(s.encode(encoding)) + else: + sys.stdout.write(s.encode(encoding)) + + +if PY3: + basestring = str + unicode = str # pylint: disable=redefined-builtin,invalid-name +else: + basestring = basestring + + def unicode(s): # pylint: disable=invalid-name + """Force conversion of s to unicode.""" + return __builtin__.unicode(s, 'utf-8') + + +# In Python 3.2+, readfp is deprecated in favor of read_file, which doesn't +# exist in Python 2 yet. To avoid deprecation warnings, subclass ConfigParser to +# fix this - now read_file works across all Python versions we care about. +class ConfigParser(configparser.ConfigParser): + if not PY3: + + def read_file(self, fp, source=None): + self.readfp(fp, filename=source) + + +def removeBOM(source): + """Remove any Byte-order-Mark bytes from the beginning of a file.""" + bom = codecs.BOM_UTF8 + if PY3: + bom = bom.decode('utf-8') + if source.startswith(bom): + return source[len(bom):] + return source diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/pytree_unwrapper.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/pytree_unwrapper.py new file mode 100644 index 00000000..c7e32a3e --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/pytree_unwrapper.py @@ -0,0 +1,424 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""PyTreeUnwrapper - produces a list of unwrapped lines from a pytree. + +[for a description of what an unwrapped line is, see unwrapped_line.py] + +This is a pytree visitor that goes over a parse tree and produces a list of +UnwrappedLine containers from it, each with its own depth and containing all +the tokens that could fit on the line if there were no maximal line-length +limitations. + +Note: a precondition to running this visitor and obtaining correct results is +for the tree to have its comments spliced in as nodes. Prefixes are ignored. + +For most uses, the convenience function UnwrapPyTree should be sufficient. +""" + +# The word "token" is overloaded within this module, so for clarity rename +# the imported pgen2.token module. +from lib2to3 import pytree +from lib2to3.pgen2 import token as grammar_token + +from yapf.yapflib import format_token +from yapf.yapflib import object_state +from yapf.yapflib import pytree_utils +from yapf.yapflib import pytree_visitor +from yapf.yapflib import split_penalty +from yapf.yapflib import style +from yapf.yapflib import unwrapped_line + + +def UnwrapPyTree(tree): + """Create and return a list of unwrapped lines from the given pytree. + + Arguments: + tree: the top-level pytree node to unwrap. + + Returns: + A list of UnwrappedLine objects. + """ + unwrapper = PyTreeUnwrapper() + unwrapper.Visit(tree) + uwlines = unwrapper.GetUnwrappedLines() + uwlines.sort(key=lambda x: x.lineno) + return uwlines + + +# Grammar tokens considered as whitespace for the purpose of unwrapping. +_WHITESPACE_TOKENS = frozenset([ + grammar_token.NEWLINE, grammar_token.DEDENT, grammar_token.INDENT, + grammar_token.ENDMARKER +]) + + +class PyTreeUnwrapper(pytree_visitor.PyTreeVisitor): + """PyTreeUnwrapper - see file-level docstring for detailed description. + + Note: since this implements PyTreeVisitor and node names in lib2to3 are + underscore_separated, the visiting methods of this class are named as + Visit_node_name. invalid-name pragmas are added to each such method to silence + a style warning. This is forced on us by the usage of lib2to3, and re-munging + method names to make them different from actual node names sounded like a + confusing and brittle affair that wasn't worth it for this small & controlled + deviation from the style guide. + + To understand the connection between visitor methods in this class, some + familiarity with the Python grammar is required. + """ + + def __init__(self): + # A list of all unwrapped lines finished visiting so far. + self._unwrapped_lines = [] + + # Builds up a "current" unwrapped line while visiting pytree nodes. Some + # nodes will finish a line and start a new one. + self._cur_unwrapped_line = unwrapped_line.UnwrappedLine(0) + + # Current indentation depth. + self._cur_depth = 0 + + def GetUnwrappedLines(self): + """Fetch the result of the tree walk. + + Note: only call this after visiting the whole tree. + + Returns: + A list of UnwrappedLine objects. + """ + # Make sure the last line that was being populated is flushed. + self._StartNewLine() + return self._unwrapped_lines + + def _StartNewLine(self): + """Finish current line and start a new one. + + Place the currently accumulated line into the _unwrapped_lines list and + start a new one. + """ + if self._cur_unwrapped_line.tokens: + self._unwrapped_lines.append(self._cur_unwrapped_line) + _MatchBrackets(self._cur_unwrapped_line) + _IdentifyParameterLists(self._cur_unwrapped_line) + _AdjustSplitPenalty(self._cur_unwrapped_line) + self._cur_unwrapped_line = unwrapped_line.UnwrappedLine(self._cur_depth) + + _STMT_TYPES = frozenset({ + 'if_stmt', + 'while_stmt', + 'for_stmt', + 'try_stmt', + 'expect_clause', + 'with_stmt', + 'funcdef', + 'classdef', + }) + + # pylint: disable=invalid-name,missing-docstring + def Visit_simple_stmt(self, node): + # A 'simple_stmt' conveniently represents a non-compound Python statement, + # i.e. a statement that does not contain other statements. + + # When compound nodes have a single statement as their suite, the parser + # can leave it in the tree directly without creating a suite. But we have + # to increase depth in these cases as well. However, don't increase the + # depth of we have a simple_stmt that's a comment node. This represents a + # standalone comment and in the case of it coming directly after the + # funcdef, it is a "top" comment for the whole function. + # TODO(eliben): add more relevant compound statements here. + single_stmt_suite = ( + node.parent and pytree_utils.NodeName(node.parent) in self._STMT_TYPES) + is_comment_stmt = pytree_utils.IsCommentStatement(node) + if single_stmt_suite and not is_comment_stmt: + self._cur_depth += 1 + self._StartNewLine() + self.DefaultNodeVisit(node) + if single_stmt_suite and not is_comment_stmt: + self._cur_depth -= 1 + + def _VisitCompoundStatement(self, node, substatement_names): + """Helper for visiting compound statements. + + Python compound statements serve as containers for other statements. Thus, + when we encounter a new compound statement we start a new unwrapped line. + + Arguments: + node: the node to visit. + substatement_names: set of node names. A compound statement will be + recognized as a NAME node with a name in this set. + """ + for child in node.children: + # A pytree is structured in such a way that a single 'if_stmt' node will + # contain all the 'if', 'elif' and 'else' nodes as children (similar + # structure applies to 'while' statements, 'try' blocks, etc). Therefore, + # we visit all children here and create a new line before the requested + # set of nodes. + if (child.type == grammar_token.NAME and + child.value in substatement_names): + self._StartNewLine() + self.Visit(child) + + _IF_STMT_ELEMS = frozenset({'if', 'else', 'elif'}) + + def Visit_if_stmt(self, node): # pylint: disable=invalid-name + self._VisitCompoundStatement(node, self._IF_STMT_ELEMS) + + _WHILE_STMT_ELEMS = frozenset({'while', 'else'}) + + def Visit_while_stmt(self, node): # pylint: disable=invalid-name + self._VisitCompoundStatement(node, self._WHILE_STMT_ELEMS) + + _FOR_STMT_ELEMS = frozenset({'for', 'else'}) + + def Visit_for_stmt(self, node): # pylint: disable=invalid-name + self._VisitCompoundStatement(node, self._FOR_STMT_ELEMS) + + _TRY_STMT_ELEMS = frozenset({'try', 'except', 'else', 'finally'}) + + def Visit_try_stmt(self, node): # pylint: disable=invalid-name + self._VisitCompoundStatement(node, self._TRY_STMT_ELEMS) + + _EXCEPT_STMT_ELEMS = frozenset({'except'}) + + def Visit_except_clause(self, node): # pylint: disable=invalid-name + self._VisitCompoundStatement(node, self._EXCEPT_STMT_ELEMS) + + _FUNC_DEF_ELEMS = frozenset({'def'}) + + def Visit_funcdef(self, node): # pylint: disable=invalid-name + self._VisitCompoundStatement(node, self._FUNC_DEF_ELEMS) + + def Visit_async_funcdef(self, node): # pylint: disable=invalid-name + self._StartNewLine() + index = 0 + for child in node.children: + index += 1 + self.Visit(child) + if pytree_utils.NodeName(child) == 'ASYNC': + break + for child in node.children[index].children: + self.Visit(child) + + _CLASS_DEF_ELEMS = frozenset({'class'}) + + def Visit_classdef(self, node): # pylint: disable=invalid-name + self._VisitCompoundStatement(node, self._CLASS_DEF_ELEMS) + + def Visit_async_stmt(self, node): # pylint: disable=invalid-name + self._StartNewLine() + index = 0 + for child in node.children: + index += 1 + self.Visit(child) + if pytree_utils.NodeName(child) == 'ASYNC': + break + for child in node.children[index].children: + if pytree_utils.NodeName(child) == 'NAME' and child.value == 'else': + self._StartNewLine() + self.Visit(child) + + def Visit_decorator(self, node): # pylint: disable=invalid-name + for child in node.children: + self.Visit(child) + if (pytree_utils.NodeName(child) == 'COMMENT' and + child == node.children[0]): + self._StartNewLine() + + def Visit_decorators(self, node): # pylint: disable=invalid-name + for child in node.children: + self._StartNewLine() + self.Visit(child) + + def Visit_decorated(self, node): # pylint: disable=invalid-name + for child in node.children: + self._StartNewLine() + self.Visit(child) + + _WITH_STMT_ELEMS = frozenset({'with'}) + + def Visit_with_stmt(self, node): # pylint: disable=invalid-name + self._VisitCompoundStatement(node, self._WITH_STMT_ELEMS) + + def Visit_suite(self, node): # pylint: disable=invalid-name + # A 'suite' starts a new indentation level in Python. + self._cur_depth += 1 + self._StartNewLine() + self.DefaultNodeVisit(node) + self._cur_depth -= 1 + + def Visit_listmaker(self, node): # pylint: disable=invalid-name + _DetermineMustSplitAnnotation(node) + self.DefaultNodeVisit(node) + + def Visit_dictsetmaker(self, node): # pylint: disable=invalid-name + _DetermineMustSplitAnnotation(node) + self.DefaultNodeVisit(node) + + def Visit_import_as_names(self, node): # pylint: disable=invalid-name + if node.prev_sibling.value == '(': + _DetermineMustSplitAnnotation(node) + self.DefaultNodeVisit(node) + + def Visit_testlist_gexp(self, node): # pylint: disable=invalid-name + _DetermineMustSplitAnnotation(node) + self.DefaultNodeVisit(node) + + def Visit_arglist(self, node): # pylint: disable=invalid-name + _DetermineMustSplitAnnotation(node) + self.DefaultNodeVisit(node) + + def Visit_typedargslist(self, node): # pylint: disable=invalid-name + _DetermineMustSplitAnnotation(node) + self.DefaultNodeVisit(node) + + def DefaultLeafVisit(self, leaf): + """Default visitor for tree leaves. + + A tree leaf is always just gets appended to the current unwrapped line. + + Arguments: + leaf: the leaf to visit. + """ + if leaf.type in _WHITESPACE_TOKENS: + self._StartNewLine() + elif leaf.type != grammar_token.COMMENT or leaf.value.strip(): + # Add non-whitespace tokens and comments that aren't empty. + self._cur_unwrapped_line.AppendNode(leaf) + + +_BRACKET_MATCH = {')': '(', '}': '{', ']': '['} + + +def _MatchBrackets(uwline): + """Visit the node and match the brackets. + + For every open bracket ('[', '{', or '('), find the associated closing bracket + and "match" them up. I.e., save in the token a pointer to its associated open + or close bracket. + + Arguments: + uwline: (UnwrappedLine) An unwrapped line. + """ + bracket_stack = [] + for token in uwline.tokens: + if token.value in pytree_utils.OPENING_BRACKETS: + bracket_stack.append(token) + elif token.value in pytree_utils.CLOSING_BRACKETS: + bracket_stack[-1].matching_bracket = token + token.matching_bracket = bracket_stack[-1] + bracket_stack.pop() + + for bracket in bracket_stack: + if id(pytree_utils.GetOpeningBracket(token.node)) == id(bracket.node): + bracket.container_elements.append(token) + token.container_opening = bracket + + +def _IdentifyParameterLists(uwline): + """Visit the node to create a state for parameter lists. + + For instance, a parameter is considered an "object" with its first and last + token uniquely identifying the object. + + Arguments: + uwline: (UnwrappedLine) An unwrapped line. + """ + func_stack = [] + param_stack = [] + for tok in uwline.tokens: + # Identify parameter list objects. + if format_token.Subtype.FUNC_DEF in tok.subtypes: + assert tok.next_token.value == '(' + func_stack.append(tok.next_token) + continue + + if func_stack and tok.value == ')': + if tok == func_stack[-1].matching_bracket: + func_stack.pop() + continue + + # Identify parameter objects. + if format_token.Subtype.PARAMETER_START in tok.subtypes: + param_stack.append(tok) + + # Not "elif", a parameter could be a single token. + if param_stack and format_token.Subtype.PARAMETER_STOP in tok.subtypes: + start = param_stack.pop() + func_stack[-1].parameters.append(object_state.Parameter(start, tok)) + + +def _AdjustSplitPenalty(uwline): + """Visit the node and adjust the split penalties if needed. + + A token shouldn't be split if it's not within a bracket pair. Mark any token + that's not within a bracket pair as "unbreakable". + + Arguments: + uwline: (UnwrappedLine) An unwrapped line. + """ + bracket_level = 0 + for index, token in enumerate(uwline.tokens): + if index and not bracket_level: + pytree_utils.SetNodeAnnotation(token.node, + pytree_utils.Annotation.SPLIT_PENALTY, + split_penalty.UNBREAKABLE) + if token.value in pytree_utils.OPENING_BRACKETS: + bracket_level += 1 + elif token.value in pytree_utils.CLOSING_BRACKETS: + bracket_level -= 1 + + +def _DetermineMustSplitAnnotation(node): + """Enforce a split in the list if the list ends with a comma.""" + if style.Get('DISABLE_ENDING_COMMA_HEURISTIC'): + return + if not _ContainsComments(node): + token = next(node.parent.leaves()) + if token.value == '(': + if sum(1 for ch in node.children + if pytree_utils.NodeName(ch) == 'COMMA') < 2: + return + if (not isinstance(node.children[-1], pytree.Leaf) or + node.children[-1].value != ','): + return + num_children = len(node.children) + index = 0 + _SetMustSplitOnFirstLeaf(node.children[0]) + while index < num_children - 1: + child = node.children[index] + if isinstance(child, pytree.Leaf) and child.value == ',': + next_child = node.children[index + 1] + if next_child.type == grammar_token.COMMENT: + index += 1 + if index >= num_children - 1: + break + _SetMustSplitOnFirstLeaf(node.children[index + 1]) + index += 1 + + +def _ContainsComments(node): + """Return True if the list has a comment in it.""" + if isinstance(node, pytree.Leaf): + return node.type == grammar_token.COMMENT + for child in node.children: + if _ContainsComments(child): + return True + return False + + +def _SetMustSplitOnFirstLeaf(node): + """Set the "must split" annotation on the first leaf node.""" + pytree_utils.SetNodeAnnotation( + pytree_utils.FirstLeafNode(node), pytree_utils.Annotation.MUST_SPLIT, + True) diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/pytree_utils.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/pytree_utils.py new file mode 100644 index 00000000..75d4ca20 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/pytree_utils.py @@ -0,0 +1,346 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""pytree-related utilities. + +This module collects various utilities related to the parse trees produced by +the lib2to3 library. + + NodeName(): produces a string name for pytree nodes. + ParseCodeToTree(): convenience wrapper around lib2to3 interfaces to parse + a given string with code to a pytree. + InsertNodeBefore(): insert a node before another in a pytree. + InsertNodeAfter(): insert a node after another in a pytree. + {Get,Set}NodeAnnotation(): manage custom annotations on pytree nodes. +""" + +import ast + +from lib2to3 import pygram +from lib2to3 import pytree +from lib2to3.pgen2 import driver +from lib2to3.pgen2 import parse +from lib2to3.pgen2 import token + +# TODO(eliben): We may want to get rid of this filtering at some point once we +# have a better understanding of what information we need from the tree. Then, +# these tokens may be filtered out from the tree before the tree gets to the +# unwrapper. +NONSEMANTIC_TOKENS = frozenset(['DEDENT', 'INDENT', 'NEWLINE', 'ENDMARKER']) + +OPENING_BRACKETS = frozenset({'(', '[', '{'}) +CLOSING_BRACKETS = frozenset({')', ']', '}'}) + + +class Annotation(object): + """Annotation names associated with pytrees.""" + CHILD_INDENT = 'child_indent' + NEWLINES = 'newlines' + MUST_SPLIT = 'must_split' + SPLIT_PENALTY = 'split_penalty' + SUBTYPE = 'subtype' + + +def NodeName(node): + """Produce a string name for a given node. + + For a Leaf this is the token name, and for a Node this is the type. + + Arguments: + node: a tree node + + Returns: + Name as a string. + """ + # Nodes with values < 256 are tokens. Values >= 256 are grammar symbols. + if node.type < 256: + return token.tok_name[node.type] + else: + return pygram.python_grammar.number2symbol[node.type] + + +def FirstLeafNode(node): + if isinstance(node, pytree.Leaf): + return node + return FirstLeafNode(node.children[0]) + + +def LastLeafNode(node): + if isinstance(node, pytree.Leaf): + return node + return LastLeafNode(node.children[-1]) + + +# lib2to3 thoughtfully provides pygram.python_grammar_no_print_statement for +# parsing Python 3 code that wouldn't parse otherwise (when 'print' is used in a +# context where a keyword is disallowed). +# It forgets to do the same for 'exec' though. Luckily, Python is amenable to +# monkey-patching. +_GRAMMAR_FOR_PY3 = pygram.python_grammar_no_print_statement.copy() +del _GRAMMAR_FOR_PY3.keywords['exec'] + +_GRAMMAR_FOR_PY2 = pygram.python_grammar.copy() +del _GRAMMAR_FOR_PY2.keywords['nonlocal'] + + +def ParseCodeToTree(code): + """Parse the given code to a lib2to3 pytree. + + Arguments: + code: a string with the code to parse. + + Raises: + SyntaxError if the code is invalid syntax. + parse.ParseError if some other parsing failure. + + Returns: + The root node of the parsed tree. + """ + # This function is tiny, but the incantation for invoking the parser correctly + # is sufficiently magical to be worth abstracting away. + try: + # Try to parse using a Python 3 grammar, which is more permissive (print and + # exec are not keywords). + parser_driver = driver.Driver(_GRAMMAR_FOR_PY3, convert=pytree.convert) + tree = parser_driver.parse_string(code, debug=False) + except parse.ParseError: + # Now try to parse using a Python 2 grammar; If this fails, then + # there's something else wrong with the code. + try: + parser_driver = driver.Driver(_GRAMMAR_FOR_PY2, convert=pytree.convert) + tree = parser_driver.parse_string(code, debug=False) + except parse.ParseError: + # Raise a syntax error if the code is invalid python syntax. + try: + ast.parse(code) + except SyntaxError as e: + raise e + else: + raise + return _WrapEndMarker(tree) + + +def _WrapEndMarker(tree): + """Wrap a single ENDMARKER token in a "file_input" node. + + Arguments: + tree: (pytree.Node) The root node of the parsed tree. + + Returns: + The root node of the parsed tree. If the tree is a single ENDMARKER node, + then that node is wrapped in a "file_input" node. That will ensure we don't + skip comments attached to that node. + """ + if isinstance(tree, pytree.Leaf) and tree.type == token.ENDMARKER: + return pytree.Node(pygram.python_symbols.file_input, [tree]) + return tree + + +def InsertNodesBefore(new_nodes, target): + """Insert new_nodes before the given target location in the tree. + + Arguments: + new_nodes: a sequence of new nodes to insert (the nodes should not be in the + tree). + target: the target node before which the new node node will be inserted. + + Raises: + RuntimeError: if the tree is corrupted, or the insertion would corrupt it. + """ + for node in new_nodes: + _InsertNodeAt(node, target, after=False) + + +def InsertNodesAfter(new_nodes, target): + """Insert new_nodes after the given target location in the tree. + + Arguments: + new_nodes: a sequence of new nodes to insert (the nodes should not be in the + tree). + target: the target node after which the new node node will be inserted. + + Raises: + RuntimeError: if the tree is corrupted, or the insertion would corrupt it. + """ + for node in reversed(new_nodes): + _InsertNodeAt(node, target, after=True) + + +def _InsertNodeAt(new_node, target, after=False): + """Underlying implementation for node insertion. + + Arguments: + new_node: a new node to insert (this node should not be in the tree). + target: the target node. + after: if True, new_node is inserted after target. Otherwise, it's inserted + before target. + + Returns: + nothing + + Raises: + RuntimeError: if the tree is corrupted, or the insertion would corrupt it. + """ + + # Protect against attempts to insert nodes which already belong to some tree. + if new_node.parent is not None: + raise RuntimeError('inserting node which already has a parent', + (new_node, new_node.parent)) + + # The code here is based on pytree.Base.next_sibling + parent_of_target = target.parent + if parent_of_target is None: + raise RuntimeError('expected target node to have a parent', (target,)) + + for i, child in enumerate(parent_of_target.children): + if child is target: + insertion_index = i + 1 if after else i + parent_of_target.insert_child(insertion_index, new_node) + return + + raise RuntimeError('unable to find insertion point for target node', + (target,)) + + +# The following constant and functions implement a simple custom annotation +# mechanism for pytree nodes. We attach new attributes to nodes. Each attribute +# is prefixed with _NODE_ANNOTATION_PREFIX. These annotations should only be +# managed through GetNodeAnnotation and SetNodeAnnotation. +_NODE_ANNOTATION_PREFIX = '_yapf_annotation_' + + +def CopyYapfAnnotations(src, dst): + """Copy all YAPF annotations from the source node to the destination node. + + Arguments: + src: the source node. + dst: the destination node. + """ + for annotation in dir(src): + if annotation.startswith(_NODE_ANNOTATION_PREFIX): + setattr(dst, annotation, getattr(src, annotation, None)) + + +def GetNodeAnnotation(node, annotation, default=None): + """Get annotation value from a node. + + Arguments: + node: the node. + annotation: annotation name - a string. + default: the default value to return if there's no annotation. + + Returns: + Value of the annotation in the given node. If the node doesn't have this + particular annotation name yet, returns default. + """ + return getattr(node, _NODE_ANNOTATION_PREFIX + annotation, default) + + +def SetNodeAnnotation(node, annotation, value): + """Set annotation value on a node. + + Arguments: + node: the node. + annotation: annotation name - a string. + value: annotation value to set. + """ + setattr(node, _NODE_ANNOTATION_PREFIX + annotation, value) + + +def AppendNodeAnnotation(node, annotation, value): + """Appends an annotation value to a list of annotations on the node. + + Arguments: + node: the node. + annotation: annotation name - a string. + value: annotation value to set. + """ + attr = GetNodeAnnotation(node, annotation, set()) + attr.add(value) + SetNodeAnnotation(node, annotation, attr) + + +def RemoveSubtypeAnnotation(node, value): + """Removes an annotation value from the subtype annotations on the node. + + Arguments: + node: the node. + value: annotation value to remove. + """ + attr = GetNodeAnnotation(node, Annotation.SUBTYPE) + if attr and value in attr: + attr.remove(value) + SetNodeAnnotation(node, Annotation.SUBTYPE, attr) + + +def GetOpeningBracket(node): + """Get opening bracket value from a node. + + Arguments: + node: the node. + + Returns: + The opening bracket node or None if it couldn't find one. + """ + return getattr(node, _NODE_ANNOTATION_PREFIX + 'container_bracket', None) + + +def SetOpeningBracket(node, bracket): + """Set opening bracket value for a node. + + Arguments: + node: the node. + bracket: opening bracket to set. + """ + setattr(node, _NODE_ANNOTATION_PREFIX + 'container_bracket', bracket) + + +def DumpNodeToString(node): + """Dump a string representation of the given node. For debugging. + + Arguments: + node: the node. + + Returns: + The string representation. + """ + if isinstance(node, pytree.Leaf): + fmt = ('{name}({value}) [lineno={lineno}, column={column}, ' + 'prefix={prefix}, penalty={penalty}]') + return fmt.format( + name=NodeName(node), + value=_PytreeNodeRepr(node), + lineno=node.lineno, + column=node.column, + prefix=repr(node.prefix), + penalty=GetNodeAnnotation(node, Annotation.SPLIT_PENALTY, None)) + else: + fmt = '{node} [{len} children] [child_indent="{indent}"]' + return fmt.format( + node=NodeName(node), + len=len(node.children), + indent=GetNodeAnnotation(node, Annotation.CHILD_INDENT)) + + +def _PytreeNodeRepr(node): + """Like pytree.Node.__repr__, but names instead of numbers for tokens.""" + if isinstance(node, pytree.Node): + return '%s(%s, %r)' % (node.__class__.__name__, NodeName(node), + [_PytreeNodeRepr(c) for c in node.children]) + if isinstance(node, pytree.Leaf): + return '%s(%s, %r)' % (node.__class__.__name__, NodeName(node), node.value) + + +def IsCommentStatement(node): + return (NodeName(node) == 'simple_stmt' and + node.children[0].type == token.COMMENT) diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/pytree_visitor.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/pytree_visitor.py new file mode 100644 index 00000000..49da0566 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/pytree_visitor.py @@ -0,0 +1,135 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Generic visitor pattern for pytrees. + +The lib2to3 parser produces a "pytree" - syntax tree consisting of Node +and Leaf types. This module implements a visitor pattern for such trees. + +It also exports a basic "dumping" visitor that dumps a textual representation of +a pytree into a stream. + + PyTreeVisitor: a generic visitor pattern fo pytrees. + PyTreeDumper: a configurable "dumper" for displaying pytrees. + DumpPyTree(): a convenience function to dump a pytree. +""" + +import sys + +from lib2to3 import pytree + +from yapf.yapflib import pytree_utils + + +class PyTreeVisitor(object): + """Visitor pattern for pytree trees. + + Methods named Visit_XXX will be invoked when a node with type XXX is + encountered in the tree. The type is either a token type (for Leaf nodes) or + grammar symbols (for Node nodes). The return value of Visit_XXX methods is + ignored by the visitor. + + Visitors can modify node contents but must not change the tree structure + (e.g. add/remove children and move nodes around). + + This is a very common visitor pattern in Python code; it's also used in the + Python standard library ast module for providing AST visitors. + + Note: this makes names that aren't style conformant, so such visitor methods + need to be marked with # pylint: disable=invalid-name We don't have a choice + here, because lib2to3 nodes have under_separated names. + + For more complex behavior, the visit, DefaultNodeVisit and DefaultLeafVisit + methods can be overridden. Don't forget to invoke DefaultNodeVisit for nodes + that may have children - otherwise the children will not be visited. + """ + + def Visit(self, node): + """Visit a node.""" + method = 'Visit_{0}'.format(pytree_utils.NodeName(node)) + if hasattr(self, method): + # Found a specific visitor for this node + getattr(self, method)(node) + else: + if isinstance(node, pytree.Leaf): + self.DefaultLeafVisit(node) + else: + self.DefaultNodeVisit(node) + + def DefaultNodeVisit(self, node): + """Default visitor for Node: visits the node's children depth-first. + + This method is invoked when no specific visitor for the node is defined. + + Arguments: + node: the node to visit + """ + for child in node.children: + self.Visit(child) + + def DefaultLeafVisit(self, leaf): + """Default visitor for Leaf: no-op. + + This method is invoked when no specific visitor for the leaf is defined. + + Arguments: + leaf: the leaf to visit + """ + pass + + +def DumpPyTree(tree, target_stream=sys.stdout): + """Convenience function for dumping a given pytree. + + This function presents a very minimal interface. For more configurability (for + example, controlling how specific node types are displayed), use PyTreeDumper + directly. + + Arguments: + tree: the tree to dump. + target_stream: the stream to dump the tree to. A file-like object. By + default will dump into stdout. + """ + dumper = PyTreeDumper(target_stream) + dumper.Visit(tree) + + +class PyTreeDumper(PyTreeVisitor): + """Visitor that dumps the tree to a stream. + + Implements the PyTreeVisitor interface. + """ + + def __init__(self, target_stream=sys.stdout): + """Create a tree dumper. + + Arguments: + target_stream: the stream to dump the tree to. A file-like object. By + default will dump into stdout. + """ + self._target_stream = target_stream + self._current_indent = 0 + + def _DumpString(self, s): + self._target_stream.write('{0}{1}\n'.format(' ' * self._current_indent, s)) + + def DefaultNodeVisit(self, node): + # Dump information about the current node, and then use the generic + # DefaultNodeVisit visitor to dump each of its children. + self._DumpString(pytree_utils.DumpNodeToString(node)) + self._current_indent += 2 + super(PyTreeDumper, self).DefaultNodeVisit(node) + self._current_indent -= 2 + + def DefaultLeafVisit(self, leaf): + self._DumpString(pytree_utils.DumpNodeToString(leaf)) diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/reformatter.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/reformatter.py new file mode 100644 index 00000000..60386e51 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/reformatter.py @@ -0,0 +1,800 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Decide what the format for the code should be. + +The `unwrapped_line.UnwrappedLine`s are now ready to be formatted. +UnwrappedLines that can be merged together are. The best formatting is returned +as a string. + + Reformat(): the main function exported by this module. +""" + +from __future__ import unicode_literals +import collections +import heapq +import re + +from lib2to3 import pytree +from lib2to3.pgen2 import token + +from yapf.yapflib import format_decision_state +from yapf.yapflib import format_token +from yapf.yapflib import line_joiner +from yapf.yapflib import pytree_utils +from yapf.yapflib import style +from yapf.yapflib import verifier + + +def Reformat(uwlines, verify=False, lines=None): + """Reformat the unwrapped lines. + + Arguments: + uwlines: (list of unwrapped_line.UnwrappedLine) Lines we want to format. + verify: (bool) True if reformatted code should be verified for syntax. + lines: (set of int) The lines which can be modified or None if there is no + line range restriction. + + Returns: + A string representing the reformatted code. + """ + final_lines = [] + prev_uwline = None # The previous line. + indent_width = style.Get('INDENT_WIDTH') + + for uwline in _SingleOrMergedLines(uwlines): + first_token = uwline.first + _FormatFirstToken(first_token, uwline.depth, prev_uwline, final_lines) + + indent_amt = indent_width * uwline.depth + state = format_decision_state.FormatDecisionState(uwline, indent_amt) + state.MoveStateToNextToken() + + if not uwline.disable: + if uwline.first.is_comment: + uwline.first.node.value = uwline.first.node.value.rstrip() + elif uwline.last.is_comment: + uwline.last.node.value = uwline.last.node.value.rstrip() + if prev_uwline and prev_uwline.disable: + # Keep the vertical spacing between a disabled and enabled formatting + # region. + _RetainRequiredVerticalSpacingBetweenTokens(uwline.first, + prev_uwline.last, lines) + if any(tok.is_comment for tok in uwline.tokens): + _RetainVerticalSpacingBeforeComments(uwline) + + if uwline.disable or _LineHasContinuationMarkers(uwline): + _RetainHorizontalSpacing(uwline) + _RetainRequiredVerticalSpacing(uwline, prev_uwline, lines) + _EmitLineUnformatted(state) + + elif (_LineContainsPylintDisableLineTooLong(uwline) or + _LineContainsI18n(uwline)): + # Don't modify vertical spacing, but fix any horizontal spacing issues. + _RetainRequiredVerticalSpacing(uwline, prev_uwline, lines) + _EmitLineUnformatted(state) + + elif _CanPlaceOnSingleLine(uwline) and not any(tok.must_split + for tok in uwline.tokens): + # The unwrapped line fits on one line. + while state.next_token: + state.AddTokenToState(newline=False, dry_run=False) + + else: + if not _AnalyzeSolutionSpace(state): + # Failsafe mode. If there isn't a solution to the line, then just emit + # it as is. + state = format_decision_state.FormatDecisionState(uwline, indent_amt) + state.MoveStateToNextToken() + _RetainHorizontalSpacing(uwline) + _RetainRequiredVerticalSpacing(uwline, prev_uwline, None) + _EmitLineUnformatted(state) + + final_lines.append(uwline) + prev_uwline = uwline + + _AlignTrailingComments(final_lines) + return _FormatFinalLines(final_lines, verify) + + +def _RetainHorizontalSpacing(uwline): + """Retain all horizontal spacing between tokens.""" + for tok in uwline.tokens: + tok.RetainHorizontalSpacing(uwline.first.column, uwline.depth) + + +def _RetainRequiredVerticalSpacing(cur_uwline, prev_uwline, lines): + """Retain all vertical spacing between lines.""" + prev_tok = None + if prev_uwline is not None: + prev_tok = prev_uwline.last + + for cur_tok in cur_uwline.tokens: + _RetainRequiredVerticalSpacingBetweenTokens(cur_tok, prev_tok, lines) + + prev_tok = cur_tok + if cur_uwline.disable: + # After the first token we are acting on a single line. So if it is + # disabled we must not reformat. + lines = set() + + +def _RetainRequiredVerticalSpacingBetweenTokens(cur_tok, prev_tok, lines): + """Retain vertical spacing between two tokens if not in editable range.""" + if prev_tok is None: + return + + if prev_tok.is_string: + prev_lineno = prev_tok.lineno + prev_tok.value.count('\n') + elif prev_tok.is_pseudo_paren: + if not prev_tok.previous_token.is_multiline_string: + prev_lineno = prev_tok.previous_token.lineno + else: + prev_lineno = prev_tok.lineno + else: + prev_lineno = prev_tok.lineno + + if cur_tok.is_comment: + cur_lineno = cur_tok.lineno - cur_tok.value.count('\n') + else: + cur_lineno = cur_tok.lineno + + if not prev_tok.is_comment and prev_tok.value.endswith('\\'): + prev_lineno += prev_tok.value.count('\n') + + required_newlines = cur_lineno - prev_lineno + if cur_tok.is_comment and not prev_tok.is_comment: + # Don't adjust between a comment and non-comment. + pass + elif lines and lines.intersection(range(prev_lineno, cur_lineno + 1)): + desired_newlines = cur_tok.whitespace_prefix.count('\n') + whitespace_lines = range(prev_lineno + 1, cur_lineno) + deletable_lines = len(lines.intersection(whitespace_lines)) + required_newlines = max(required_newlines - deletable_lines, + desired_newlines) + + cur_tok.AdjustNewlinesBefore(required_newlines) + + +def _RetainVerticalSpacingBeforeComments(uwline): + """Retain vertical spacing before comments.""" + prev_token = None + for tok in uwline.tokens: + if tok.is_comment and prev_token: + if tok.lineno - tok.value.count('\n') - prev_token.lineno > 1: + tok.AdjustNewlinesBefore(ONE_BLANK_LINE) + + prev_token = tok + + +def _EmitLineUnformatted(state): + """Emit the line without formatting. + + The line contains code that if reformatted would break a non-syntactic + convention. E.g., i18n comments and function calls are tightly bound by + convention. Instead, we calculate when / if a newline should occur and honor + that. But otherwise the code emitted will be the same as the original code. + + Arguments: + state: (format_decision_state.FormatDecisionState) The format decision + state. + """ + while state.next_token: + previous_token = state.next_token.previous_token + previous_lineno = previous_token.lineno + + if previous_token.is_multiline_string or previous_token.is_string: + previous_lineno += previous_token.value.count('\n') + + if previous_token.is_continuation: + newline = False + else: + newline = state.next_token.lineno > previous_lineno + + state.AddTokenToState(newline=newline, dry_run=False) + + +def _LineContainsI18n(uwline): + """Return true if there are i18n comments or function calls in the line. + + I18n comments and pseudo-function calls are closely related. They cannot + be moved apart without breaking i18n. + + Arguments: + uwline: (unwrapped_line.UnwrappedLine) The line currently being formatted. + + Returns: + True if the line contains i18n comments or function calls. False otherwise. + """ + if style.Get('I18N_COMMENT'): + for tok in uwline.tokens: + if tok.is_comment and re.match(style.Get('I18N_COMMENT'), tok.value): + # Contains an i18n comment. + return True + + if style.Get('I18N_FUNCTION_CALL'): + length = len(uwline.tokens) + index = 0 + while index < length - 1: + if (uwline.tokens[index + 1].value == '(' and + uwline.tokens[index].value in style.Get('I18N_FUNCTION_CALL')): + return True + index += 1 + + return False + + +def _LineContainsPylintDisableLineTooLong(uwline): + """Return true if there is a "pylint: disable=line-too-long" comment.""" + return re.search(r'\bpylint:\s+disable=line-too-long\b', uwline.last.value) + + +def _LineHasContinuationMarkers(uwline): + """Return true if the line has continuation markers in it.""" + return any(tok.is_continuation for tok in uwline.tokens) + + +def _CanPlaceOnSingleLine(uwline): + """Determine if the unwrapped line can go on a single line. + + Arguments: + uwline: (unwrapped_line.UnwrappedLine) The line currently being formatted. + + Returns: + True if the line can or should be added to a single line. False otherwise. + """ + token_names = [x.name for x in uwline.tokens] + if (style.Get('FORCE_MULTILINE_DICT') and 'LBRACE' in token_names): + return False + indent_amt = style.Get('INDENT_WIDTH') * uwline.depth + last = uwline.last + last_index = -1 + if (last.is_pylint_comment or last.is_pytype_comment or + last.is_copybara_comment): + last = last.previous_token + last_index = -2 + if last is None: + return True + return (last.total_length + indent_amt <= style.Get('COLUMN_LIMIT') and + not any(tok.is_comment for tok in uwline.tokens[:last_index])) + + +def _AlignTrailingComments(final_lines): + """Align trailing comments to the same column.""" + final_lines_index = 0 + while final_lines_index < len(final_lines): + line = final_lines[final_lines_index] + assert line.tokens + + processed_content = False + + for tok in line.tokens: + if (tok.is_comment and isinstance(tok.spaces_required_before, list) and + tok.value.startswith('#')): + # All trailing comments and comments that appear on a line by themselves + # in this block should be indented at the same level. The block is + # terminated by an empty line or EOF. Enumerate through each line in + # the block and calculate the max line length. Once complete, use the + # first col value greater than that value and create the necessary for + # each line accordingly. + all_pc_line_lengths = [] # All pre-comment line lengths + max_line_length = 0 + + while True: + # EOF + if final_lines_index + len(all_pc_line_lengths) == len(final_lines): + break + + this_line = final_lines[final_lines_index + len(all_pc_line_lengths)] + + # Blank line - note that content is preformatted so we don't need to + # worry about spaces/tabs; a blank line will always be '\n\n'. + assert this_line.tokens + if (all_pc_line_lengths and + this_line.tokens[0].formatted_whitespace_prefix.startswith('\n\n') + ): + break + + if this_line.disable: + all_pc_line_lengths.append([]) + continue + + # Calculate the length of each line in this unwrapped line. + line_content = '' + pc_line_lengths = [] + + for line_tok in this_line.tokens: + whitespace_prefix = line_tok.formatted_whitespace_prefix + + newline_index = whitespace_prefix.rfind('\n') + if newline_index != -1: + max_line_length = max(max_line_length, len(line_content)) + line_content = '' + + whitespace_prefix = whitespace_prefix[newline_index + 1:] + + if line_tok.is_comment: + pc_line_lengths.append(len(line_content)) + else: + line_content += '{}{}'.format(whitespace_prefix, line_tok.value) + + if pc_line_lengths: + max_line_length = max(max_line_length, max(pc_line_lengths)) + + all_pc_line_lengths.append(pc_line_lengths) + + # Calculate the aligned column value + max_line_length += 2 + + aligned_col = None + for potential_col in tok.spaces_required_before: + if potential_col > max_line_length: + aligned_col = potential_col + break + + if aligned_col is None: + aligned_col = max_line_length + + # Update the comment token values based on the aligned values + for all_pc_line_lengths_index, pc_line_lengths in enumerate( + all_pc_line_lengths): + if not pc_line_lengths: + continue + + this_line = final_lines[final_lines_index + all_pc_line_lengths_index] + + pc_line_length_index = 0 + for line_tok in this_line.tokens: + if line_tok.is_comment: + assert pc_line_length_index < len(pc_line_lengths) + assert pc_line_lengths[pc_line_length_index] < aligned_col + + # Note that there may be newlines embedded in the comments, so + # we need to apply a whitespace prefix to each line. + whitespace = ' ' * ( + aligned_col - pc_line_lengths[pc_line_length_index] - 1) + pc_line_length_index += 1 + + line_content = [] + + for comment_line_index, comment_line in enumerate( + line_tok.value.split('\n')): + line_content.append('{}{}'.format(whitespace, + comment_line.strip())) + + if comment_line_index == 0: + whitespace = ' ' * (aligned_col - 1) + + line_content = '\n'.join(line_content) + + # Account for initial whitespace already slated for the + # beginning of the line. + existing_whitespace_prefix = \ + line_tok.formatted_whitespace_prefix.lstrip('\n') + + if line_content.startswith(existing_whitespace_prefix): + line_content = line_content[len(existing_whitespace_prefix):] + + line_tok.value = line_content + + assert pc_line_length_index == len(pc_line_lengths) + + final_lines_index += len(all_pc_line_lengths) + + processed_content = True + break + + if not processed_content: + final_lines_index += 1 + + +def _FormatFinalLines(final_lines, verify): + """Compose the final output from the finalized lines.""" + formatted_code = [] + for line in final_lines: + formatted_line = [] + for tok in line.tokens: + if not tok.is_pseudo_paren: + formatted_line.append(tok.formatted_whitespace_prefix) + formatted_line.append(tok.value) + else: + if (not tok.next_token.whitespace_prefix.startswith('\n') and + not tok.next_token.whitespace_prefix.startswith(' ')): + if (tok.previous_token.value == ':' or + tok.next_token.value not in ',}])'): + formatted_line.append(' ') + + formatted_code.append(''.join(formatted_line)) + if verify: + verifier.VerifyCode(formatted_code[-1]) + + return ''.join(formatted_code) + '\n' + + +class _StateNode(object): + """An edge in the solution space from 'previous.state' to 'state'. + + Attributes: + state: (format_decision_state.FormatDecisionState) The format decision state + for this node. + newline: If True, then on the edge from 'previous.state' to 'state' a + newline is inserted. + previous: (_StateNode) The previous state node in the graph. + """ + + # TODO(morbo): Add a '__cmp__' method. + + def __init__(self, state, newline, previous): + self.state = state.Clone() + self.newline = newline + self.previous = previous + + def __repr__(self): # pragma: no cover + return 'StateNode(state=[\n{0}\n], newline={1})'.format( + self.state, self.newline) + + +# A tuple of (penalty, count) that is used to prioritize the BFS. In case of +# equal penalties, we prefer states that were inserted first. During state +# generation, we make sure that we insert states first that break the line as +# late as possible. +_OrderedPenalty = collections.namedtuple('OrderedPenalty', ['penalty', 'count']) + +# An item in the prioritized BFS search queue. The 'StateNode's 'state' has +# the given '_OrderedPenalty'. +_QueueItem = collections.namedtuple('QueueItem', + ['ordered_penalty', 'state_node']) + + +def _AnalyzeSolutionSpace(initial_state): + """Analyze the entire solution space starting from initial_state. + + This implements a variant of Dijkstra's algorithm on the graph that spans + the solution space (LineStates are the nodes). The algorithm tries to find + the shortest path (the one with the lowest penalty) from 'initial_state' to + the state where all tokens are placed. + + Arguments: + initial_state: (format_decision_state.FormatDecisionState) The initial state + to start the search from. + + Returns: + True if a formatting solution was found. False otherwise. + """ + count = 0 + seen = set() + p_queue = [] + + # Insert start element. + node = _StateNode(initial_state, False, None) + heapq.heappush(p_queue, _QueueItem(_OrderedPenalty(0, count), node)) + + count += 1 + while p_queue: + item = p_queue[0] + penalty = item.ordered_penalty.penalty + node = item.state_node + if not node.state.next_token: + break + heapq.heappop(p_queue) + + if count > 10000: + node.state.ignore_stack_for_comparison = True + + if node.state in seen: + continue + + seen.add(node.state) + + # FIXME(morbo): Add a 'decision' element? + + count = _AddNextStateToQueue(penalty, node, False, count, p_queue) + count = _AddNextStateToQueue(penalty, node, True, count, p_queue) + + if not p_queue: + # We weren't able to find a solution. Do nothing. + return False + + _ReconstructPath(initial_state, heapq.heappop(p_queue).state_node) + return True + + +def _AddNextStateToQueue(penalty, previous_node, newline, count, p_queue): + """Add the following state to the analysis queue. + + Assume the current state is 'previous_node' and has been reached with a + penalty of 'penalty'. Insert a line break if 'newline' is True. + + Arguments: + penalty: (int) The penalty associated with the path up to this point. + previous_node: (_StateNode) The last _StateNode inserted into the priority + queue. + newline: (bool) Add a newline if True. + count: (int) The number of elements in the queue. + p_queue: (heapq) The priority queue representing the solution space. + + Returns: + The updated number of elements in the queue. + """ + must_split = previous_node.state.MustSplit() + if newline and not previous_node.state.CanSplit(must_split): + # Don't add a newline if the token cannot be split. + return count + if not newline and must_split: + # Don't add a token we must split but where we aren't splitting. + return count + + node = _StateNode(previous_node.state, newline, previous_node) + penalty += node.state.AddTokenToState( + newline=newline, dry_run=True, must_split=must_split) + heapq.heappush(p_queue, _QueueItem(_OrderedPenalty(penalty, count), node)) + return count + 1 + + +def _ReconstructPath(initial_state, current): + """Reconstruct the path through the queue with lowest penalty. + + Arguments: + initial_state: (format_decision_state.FormatDecisionState) The initial state + to start the search from. + current: (_StateNode) The node in the decision graph that is the end point + of the path with the least penalty. + """ + path = collections.deque() + + while current.previous: + path.appendleft(current) + current = current.previous + + for node in path: + initial_state.AddTokenToState(newline=node.newline, dry_run=False) + + +NESTED_DEPTH = [] + + +def _FormatFirstToken(first_token, indent_depth, prev_uwline, final_lines): + """Format the first token in the unwrapped line. + + Add a newline and the required indent before the first token of the unwrapped + line. + + Arguments: + first_token: (format_token.FormatToken) The first token in the unwrapped + line. + indent_depth: (int) The line's indentation depth. + prev_uwline: (list of unwrapped_line.UnwrappedLine) The unwrapped line + previous to this line. + final_lines: (list of unwrapped_line.UnwrappedLine) The unwrapped lines + that have already been processed. + """ + global NESTED_DEPTH + while NESTED_DEPTH and NESTED_DEPTH[-1] > indent_depth: + NESTED_DEPTH.pop() + + first_nested = False + if _IsClassOrDef(first_token): + if not NESTED_DEPTH: + NESTED_DEPTH = [indent_depth] + elif NESTED_DEPTH[-1] < indent_depth: + first_nested = True + NESTED_DEPTH.append(indent_depth) + + first_token.AddWhitespacePrefix( + _CalculateNumberOfNewlines(first_token, indent_depth, prev_uwline, + final_lines, first_nested), + indent_level=indent_depth) + + +NO_BLANK_LINES = 1 +ONE_BLANK_LINE = 2 +TWO_BLANK_LINES = 3 + + +def _IsClassOrDef(tok): + if tok.value in {'class', 'def', '@'}: + return True + return (tok.next_token and tok.value == 'async' and + tok.next_token.value == 'def') + + +def _CalculateNumberOfNewlines(first_token, indent_depth, prev_uwline, + final_lines, first_nested): + """Calculate the number of newlines we need to add. + + Arguments: + first_token: (format_token.FormatToken) The first token in the unwrapped + line. + indent_depth: (int) The line's indentation depth. + prev_uwline: (list of unwrapped_line.UnwrappedLine) The unwrapped line + previous to this line. + final_lines: (list of unwrapped_line.UnwrappedLine) The unwrapped lines + that have already been processed. + first_nested: (boolean) Whether this is the first nested class or function. + + Returns: + The number of newlines needed before the first token. + """ + # TODO(morbo): Special handling for imports. + # TODO(morbo): Create a knob that can tune these. + if prev_uwline is None: + # The first line in the file. Don't add blank lines. + # FIXME(morbo): Is this correct? + if first_token.newlines is not None: + pytree_utils.SetNodeAnnotation(first_token.node, + pytree_utils.Annotation.NEWLINES, None) + return 0 + + if first_token.is_docstring: + if (prev_uwline.first.value == 'class' and + style.Get('BLANK_LINE_BEFORE_CLASS_DOCSTRING')): + # Enforce a blank line before a class's docstring. + return ONE_BLANK_LINE + elif (prev_uwline.first.value.startswith('#') and + style.Get('BLANK_LINE_BEFORE_MODULE_DOCSTRING')): + # Enforce a blank line before a module's docstring. + return ONE_BLANK_LINE + # The docstring shouldn't have a newline before it. + return NO_BLANK_LINES + + if first_token.is_name and not indent_depth: + if (prev_uwline.first.value == 'from' or + prev_uwline.first.value == 'import'): + # Support custom number of blank lines between top-level imports and + # variable definitions. + return 1 + style.Get( + 'BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES') + + prev_last_token = prev_uwline.last + if prev_last_token.is_docstring: + if (not indent_depth and first_token.value in {'class', 'def', 'async'}): + # Separate a class or function from the module-level docstring with + # appropriate number of blank lines. + return 1 + style.Get('BLANK_LINES_AROUND_TOP_LEVEL_DEFINITION') + if (first_nested and + not style.Get('BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF') and + _IsClassOrDef(first_token)): + pytree_utils.SetNodeAnnotation(first_token.node, + pytree_utils.Annotation.NEWLINES, None) + return NO_BLANK_LINES + if _NoBlankLinesBeforeCurrentToken(prev_last_token.value, first_token, + prev_last_token): + return NO_BLANK_LINES + else: + return ONE_BLANK_LINE + + if _IsClassOrDef(first_token): + # TODO(morbo): This can go once the blank line calculator is more + # sophisticated. + if not indent_depth: + # This is a top-level class or function. + is_inline_comment = prev_last_token.whitespace_prefix.count('\n') == 0 + if (not prev_uwline.disable and prev_last_token.is_comment and + not is_inline_comment): + # This token follows a non-inline comment. + if _NoBlankLinesBeforeCurrentToken(prev_last_token.value, first_token, + prev_last_token): + # Assume that the comment is "attached" to the current line. + # Therefore, we want two blank lines before the comment. + index = len(final_lines) - 1 + while index > 0: + if not final_lines[index - 1].is_comment: + break + index -= 1 + if final_lines[index - 1].first.value == '@': + final_lines[index].first.AdjustNewlinesBefore(NO_BLANK_LINES) + else: + prev_last_token.AdjustNewlinesBefore( + 1 + style.Get('BLANK_LINES_AROUND_TOP_LEVEL_DEFINITION')) + if first_token.newlines is not None: + pytree_utils.SetNodeAnnotation(first_token.node, + pytree_utils.Annotation.NEWLINES, + None) + return NO_BLANK_LINES + elif _IsClassOrDef(prev_uwline.first): + if first_nested and not style.Get( + 'BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF'): + pytree_utils.SetNodeAnnotation(first_token.node, + pytree_utils.Annotation.NEWLINES, None) + return NO_BLANK_LINES + + # Calculate how many newlines were between the original lines. We want to + # retain that formatting if it doesn't violate one of the style guide rules. + if first_token.is_comment: + first_token_lineno = first_token.lineno - first_token.value.count('\n') + else: + first_token_lineno = first_token.lineno + + prev_last_token_lineno = prev_last_token.lineno + if prev_last_token.is_multiline_string: + prev_last_token_lineno += prev_last_token.value.count('\n') + + if first_token_lineno - prev_last_token_lineno > 1: + return ONE_BLANK_LINE + + return NO_BLANK_LINES + + +def _SingleOrMergedLines(uwlines): + """Generate the lines we want to format. + + Arguments: + uwlines: (list of unwrapped_line.UnwrappedLine) Lines we want to format. + + Yields: + Either a single line, if the current line cannot be merged with the + succeeding line, or the next two lines merged into one line. + """ + index = 0 + last_was_merged = False + while index < len(uwlines): + if uwlines[index].disable: + uwline = uwlines[index] + index += 1 + while index < len(uwlines): + column = uwline.last.column + 2 + if uwlines[index].lineno != uwline.lineno: + break + if uwline.last.value != ':': + leaf = pytree.Leaf( + type=token.SEMI, value=';', context=('', (uwline.lineno, column))) + uwline.AppendToken(format_token.FormatToken(leaf)) + for tok in uwlines[index].tokens: + uwline.AppendToken(tok) + index += 1 + yield uwline + elif line_joiner.CanMergeMultipleLines(uwlines[index:], last_was_merged): + # TODO(morbo): This splice is potentially very slow. Come up with a more + # performance-friendly way of determining if two lines can be merged. + next_uwline = uwlines[index + 1] + for tok in next_uwline.tokens: + uwlines[index].AppendToken(tok) + if (len(next_uwline.tokens) == 1 and + next_uwline.first.is_multiline_string): + # This may be a multiline shebang. In that case, we want to retain the + # formatting. Otherwise, it could mess up the shell script's syntax. + uwlines[index].disable = True + yield uwlines[index] + index += 2 + last_was_merged = True + else: + yield uwlines[index] + index += 1 + last_was_merged = False + + +def _NoBlankLinesBeforeCurrentToken(text, cur_token, prev_token): + """Determine if there are no blank lines before the current token. + + The previous token is a docstring or comment. The prev_token_lineno is the + start of the text of that token. Counting the number of newlines in its text + gives us the extent and thus where the line number of the end of the + docstring or comment. After that, we just compare it to the current token's + line number to see if there are blank lines between them. + + Arguments: + text: (unicode) The text of the docstring or comment before the current + token. + cur_token: (format_token.FormatToken) The current token in the unwrapped + line. + prev_token: (format_token.FormatToken) The previous token in the unwrapped + line. + + Returns: + True if there is no blank line before the current token. + """ + cur_token_lineno = cur_token.lineno + if cur_token.is_comment: + cur_token_lineno -= cur_token.value.count('\n') + num_newlines = text.count('\n') if not prev_token.is_comment else 0 + return prev_token.lineno + num_newlines == cur_token_lineno - 1 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/split_penalty.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/split_penalty.py new file mode 100644 index 00000000..d4c3dc47 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/split_penalty.py @@ -0,0 +1,629 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Computation of split penalties before/between tokens.""" + +import re + +from lib2to3 import pytree + +from yapf.yapflib import format_token +from yapf.yapflib import py3compat +from yapf.yapflib import pytree_utils +from yapf.yapflib import pytree_visitor +from yapf.yapflib import style + +# TODO(morbo): Document the annotations in a centralized place. E.g., the +# README file. +UNBREAKABLE = 1000 * 1000 +NAMED_ASSIGN = 15000 +DOTTED_NAME = 4000 +VERY_STRONGLY_CONNECTED = 3500 +STRONGLY_CONNECTED = 3000 +CONNECTED = 500 +TOGETHER = 100 + +OR_TEST = 1000 +AND_TEST = 1100 +NOT_TEST = 1200 +COMPARISON = 1300 +STAR_EXPR = 1300 +EXPR = 1400 +XOR_EXPR = 1500 +AND_EXPR = 1700 +SHIFT_EXPR = 1800 +ARITH_EXPR = 1900 +TERM = 2000 +FACTOR = 2100 +POWER = 2200 +ATOM = 2300 +ONE_ELEMENT_ARGUMENT = 500 +SUBSCRIPT = 6000 + + +def ComputeSplitPenalties(tree): + """Compute split penalties on tokens in the given parse tree. + + Arguments: + tree: the top-level pytree node to annotate with penalties. + """ + _SplitPenaltyAssigner().Visit(tree) + + +class _SplitPenaltyAssigner(pytree_visitor.PyTreeVisitor): + """Assigns split penalties to tokens, based on parse tree structure. + + Split penalties are attached as annotations to tokens. + """ + + def Visit(self, node): + if not hasattr(node, 'is_pseudo'): # Ignore pseudo tokens. + super(_SplitPenaltyAssigner, self).Visit(node) + + def Visit_import_as_names(self, node): # pyline: disable=invalid-name + # import_as_names ::= import_as_name (',' import_as_name)* [','] + self.DefaultNodeVisit(node) + prev_child = None + for child in node.children: + if (prev_child and isinstance(prev_child, pytree.Leaf) and + prev_child.value == ','): + _SetSplitPenalty(child, style.Get('SPLIT_PENALTY_IMPORT_NAMES')) + prev_child = child + + def Visit_classdef(self, node): # pylint: disable=invalid-name + # classdef ::= 'class' NAME ['(' [arglist] ')'] ':' suite + # + # NAME + _SetUnbreakable(node.children[1]) + if len(node.children) > 4: + # opening '(' + _SetUnbreakable(node.children[2]) + # ':' + _SetUnbreakable(node.children[-2]) + self.DefaultNodeVisit(node) + + def Visit_funcdef(self, node): # pylint: disable=invalid-name + # funcdef ::= 'def' NAME parameters ['->' test] ':' suite + # + # Can't break before the function name and before the colon. The parameters + # are handled by child iteration. + colon_idx = 1 + while pytree_utils.NodeName(node.children[colon_idx]) == 'simple_stmt': + colon_idx += 1 + _SetUnbreakable(node.children[colon_idx]) + arrow_idx = -1 + while colon_idx < len(node.children): + if isinstance(node.children[colon_idx], pytree.Leaf): + if node.children[colon_idx].value == ':': + break + if node.children[colon_idx].value == '->': + arrow_idx = colon_idx + colon_idx += 1 + _SetUnbreakable(node.children[colon_idx]) + self.DefaultNodeVisit(node) + if arrow_idx > 0: + _SetSplitPenalty( + pytree_utils.LastLeafNode(node.children[arrow_idx - 1]), 0) + _SetUnbreakable(node.children[arrow_idx]) + _SetStronglyConnected(node.children[arrow_idx + 1]) + + def Visit_lambdef(self, node): # pylint: disable=invalid-name + # lambdef ::= 'lambda' [varargslist] ':' test + # Loop over the lambda up to and including the colon. + allow_multiline_lambdas = style.Get('ALLOW_MULTILINE_LAMBDAS') + if not allow_multiline_lambdas: + for child in node.children: + if pytree_utils.NodeName(child) == 'COMMENT': + if re.search(r'pylint:.*disable=.*\bg-long-lambda', child.value): + allow_multiline_lambdas = True + break + + if allow_multiline_lambdas: + _SetExpressionPenalty(node, STRONGLY_CONNECTED) + else: + _SetExpressionPenalty(node, VERY_STRONGLY_CONNECTED) + + def Visit_parameters(self, node): # pylint: disable=invalid-name + # parameters ::= '(' [typedargslist] ')' + self.DefaultNodeVisit(node) + + # Can't break before the opening paren of a parameter list. + _SetUnbreakable(node.children[0]) + if not (style.Get('INDENT_CLOSING_BRACKETS') or + style.Get('DEDENT_CLOSING_BRACKETS')): + _SetStronglyConnected(node.children[-1]) + + def Visit_arglist(self, node): # pylint: disable=invalid-name + # arglist ::= argument (',' argument)* [','] + if pytree_utils.NodeName(node.children[0]) == 'STAR': + # Python 3 treats a star expression as a specific expression type. + # Process it in that method. + self.Visit_star_expr(node) + return + + self.DefaultNodeVisit(node) + + for index in py3compat.range(1, len(node.children)): + child = node.children[index] + if isinstance(child, pytree.Leaf) and child.value == ',': + _SetUnbreakable(child) + + for child in node.children: + if pytree_utils.NodeName(child) == 'atom': + _IncreasePenalty(child, CONNECTED) + + def Visit_argument(self, node): # pylint: disable=invalid-name + # argument ::= test [comp_for] | test '=' test # Really [keyword '='] test + self.DefaultNodeVisit(node) + + for index in py3compat.range(1, len(node.children) - 1): + child = node.children[index] + if isinstance(child, pytree.Leaf) and child.value == '=': + _SetSplitPenalty( + pytree_utils.FirstLeafNode(node.children[index]), NAMED_ASSIGN) + _SetSplitPenalty( + pytree_utils.FirstLeafNode(node.children[index + 1]), NAMED_ASSIGN) + + def Visit_tname(self, node): # pylint: disable=invalid-name + # tname ::= NAME [':' test] + self.DefaultNodeVisit(node) + + for index in py3compat.range(1, len(node.children) - 1): + child = node.children[index] + if isinstance(child, pytree.Leaf) and child.value == ':': + _SetSplitPenalty( + pytree_utils.FirstLeafNode(node.children[index]), NAMED_ASSIGN) + _SetSplitPenalty( + pytree_utils.FirstLeafNode(node.children[index + 1]), NAMED_ASSIGN) + + def Visit_dotted_name(self, node): # pylint: disable=invalid-name + # dotted_name ::= NAME ('.' NAME)* + for child in node.children: + self.Visit(child) + start = 2 if hasattr(node.children[0], 'is_pseudo') else 1 + for i in py3compat.range(start, len(node.children)): + _SetUnbreakable(node.children[i]) + + def Visit_dictsetmaker(self, node): # pylint: disable=invalid-name + # dictsetmaker ::= ( (test ':' test + # (comp_for | (',' test ':' test)* [','])) | + # (test (comp_for | (',' test)* [','])) ) + for child in node.children: + self.Visit(child) + if pytree_utils.NodeName(child) == 'COLON': + # This is a key to a dictionary. We don't want to split the key if at + # all possible. + _SetStronglyConnected(child) + + def Visit_trailer(self, node): # pylint: disable=invalid-name + # trailer ::= '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME + if node.children[0].value == '.': + before = style.Get('SPLIT_BEFORE_DOT') + _SetSplitPenalty(node.children[0], + VERY_STRONGLY_CONNECTED if before else DOTTED_NAME) + _SetSplitPenalty(node.children[1], + DOTTED_NAME if before else VERY_STRONGLY_CONNECTED) + elif len(node.children) == 2: + # Don't split an empty argument list if at all possible. + _SetSplitPenalty(node.children[1], VERY_STRONGLY_CONNECTED) + elif len(node.children) == 3: + name = pytree_utils.NodeName(node.children[1]) + if name in {'argument', 'comparison'}: + # Don't split an argument list with one element if at all possible. + _SetStronglyConnected(node.children[1]) + if (len(node.children[1].children) > 1 and + pytree_utils.NodeName(node.children[1].children[1]) == 'comp_for'): + # Don't penalize splitting before a comp_for expression. + _SetSplitPenalty(pytree_utils.FirstLeafNode(node.children[1]), 0) + else: + _SetSplitPenalty( + pytree_utils.FirstLeafNode(node.children[1]), + ONE_ELEMENT_ARGUMENT) + elif (pytree_utils.NodeName(node.children[0]) == 'LSQB' and + len(node.children[1].children) > 2 and + (name.endswith('_test') or name.endswith('_expr'))): + _SetStronglyConnected(node.children[1].children[0]) + _SetStronglyConnected(node.children[1].children[2]) + + # Still allow splitting around the operator. + split_before = ((name.endswith('_test') and + style.Get('SPLIT_BEFORE_LOGICAL_OPERATOR')) or + (name.endswith('_expr') and + style.Get('SPLIT_BEFORE_BITWISE_OPERATOR'))) + if split_before: + _SetSplitPenalty( + pytree_utils.LastLeafNode(node.children[1].children[1]), 0) + else: + _SetSplitPenalty( + pytree_utils.FirstLeafNode(node.children[1].children[2]), 0) + + # Don't split the ending bracket of a subscript list. + _RecAnnotate(node.children[-1], pytree_utils.Annotation.SPLIT_PENALTY, + VERY_STRONGLY_CONNECTED) + elif name not in { + 'arglist', 'argument', 'term', 'or_test', 'and_test', 'comparison', + 'atom', 'power' + }: + # Don't split an argument list with one element if at all possible. + subtypes = pytree_utils.GetNodeAnnotation( + pytree_utils.FirstLeafNode(node), pytree_utils.Annotation.SUBTYPE) + if subtypes and format_token.Subtype.SUBSCRIPT_BRACKET in subtypes: + _IncreasePenalty(node, SUBSCRIPT) + + # Bump up the split penalty for the first part of a subscript. We + # would rather not split there. + _IncreasePenalty(node.children[1], CONNECTED) + else: + _SetStronglyConnected(node.children[1], node.children[2]) + + if name == 'arglist': + _SetStronglyConnected(node.children[-1]) + + self.DefaultNodeVisit(node) + + def Visit_power(self, node): # pylint: disable=invalid-name,missing-docstring + # power ::= atom trailer* ['**' factor] + self.DefaultNodeVisit(node) + + # When atom is followed by a trailer, we can not break between them. + # E.g. arr[idx] - no break allowed between 'arr' and '['. + if (len(node.children) > 1 and + pytree_utils.NodeName(node.children[1]) == 'trailer'): + # children[1] itself is a whole trailer: we don't want to + # mark all of it as unbreakable, only its first token: (, [ or . + first = pytree_utils.FirstLeafNode(node.children[1]) + if first.value != '.': + _SetUnbreakable(node.children[1].children[0]) + + # A special case when there are more trailers in the sequence. Given: + # atom tr1 tr2 + # The last token of tr1 and the first token of tr2 comprise an unbreakable + # region. For example: foo.bar.baz(1) + # We can't put breaks between either of the '.', '(', or '[' and the names + # *preceding* them. + prev_trailer_idx = 1 + while prev_trailer_idx < len(node.children) - 1: + cur_trailer_idx = prev_trailer_idx + 1 + cur_trailer = node.children[cur_trailer_idx] + if pytree_utils.NodeName(cur_trailer) != 'trailer': + break + + # Now we know we have two trailers one after the other + prev_trailer = node.children[prev_trailer_idx] + if prev_trailer.children[-1].value != ')': + # Set the previous node unbreakable if it's not a function call: + # atom tr1() tr2 + # It may be necessary (though undesirable) to split up a previous + # function call's parentheses to the next line. + _SetStronglyConnected(prev_trailer.children[-1]) + _SetStronglyConnected(cur_trailer.children[0]) + prev_trailer_idx = cur_trailer_idx + + # We don't want to split before the last ')' of a function call. This also + # takes care of the special case of: + # atom tr1 tr2 ... trn + # where the 'tr#' are trailers that may end in a ')'. + for trailer in node.children[1:]: + if pytree_utils.NodeName(trailer) != 'trailer': + break + if trailer.children[0].value in '([': + if len(trailer.children) > 2: + subtypes = pytree_utils.GetNodeAnnotation( + trailer.children[0], pytree_utils.Annotation.SUBTYPE) + if subtypes and format_token.Subtype.SUBSCRIPT_BRACKET in subtypes: + _SetStronglyConnected( + pytree_utils.FirstLeafNode(trailer.children[1])) + + last_child_node = pytree_utils.LastLeafNode(trailer) + if last_child_node.value.strip().startswith('#'): + last_child_node = last_child_node.prev_sibling + if not (style.Get('INDENT_CLOSING_BRACKETS') or + style.Get('DEDENT_CLOSING_BRACKETS')): + last = pytree_utils.LastLeafNode(last_child_node.prev_sibling) + if last.value != ',': + if last_child_node.value == ']': + _SetUnbreakable(last_child_node) + else: + _SetSplitPenalty(last_child_node, VERY_STRONGLY_CONNECTED) + else: + # If the trailer's children are '()', then make it a strongly + # connected region. It's sometimes necessary, though undesirable, to + # split the two. + _SetStronglyConnected(trailer.children[-1]) + + def Visit_subscriptlist(self, node): # pylint: disable=invalid-name + # subscriptlist ::= subscript (',' subscript)* [','] + self.DefaultNodeVisit(node) + _SetSplitPenalty(pytree_utils.FirstLeafNode(node), 0) + prev_child = None + for child in node.children: + if prev_child and pytree_utils.NodeName(prev_child) == 'COMMA': + _SetSplitPenalty(pytree_utils.FirstLeafNode(child), 0) + prev_child = child + + def Visit_subscript(self, node): # pylint: disable=invalid-name + # subscript ::= test | [test] ':' [test] [sliceop] + _SetStronglyConnected(*node.children) + self.DefaultNodeVisit(node) + + def Visit_comp_for(self, node): # pylint: disable=invalid-name + # comp_for ::= 'for' exprlist 'in' testlist_safe [comp_iter] + _SetSplitPenalty(pytree_utils.FirstLeafNode(node), 0) + _SetStronglyConnected(*node.children[1:]) + self.DefaultNodeVisit(node) + + def Visit_old_comp_for(self, node): # pylint: disable=invalid-name + # Python 3.7 + self.Visit_comp_for(node) + + def Visit_comp_if(self, node): # pylint: disable=invalid-name + # comp_if ::= 'if' old_test [comp_iter] + _SetSplitPenalty(node.children[0], + style.Get('SPLIT_PENALTY_BEFORE_IF_EXPR')) + _SetStronglyConnected(*node.children[1:]) + self.DefaultNodeVisit(node) + + def Visit_old_comp_if(self, node): # pylint: disable=invalid-name + # Python 3.7 + self.Visit_comp_if(node) + + def Visit_test(self, node): # pylint: disable=invalid-name + # test ::= or_test ['if' or_test 'else' test] | lambdef + _IncreasePenalty(node, OR_TEST) + self.DefaultNodeVisit(node) + + def Visit_or_test(self, node): # pylint: disable=invalid-name + # or_test ::= and_test ('or' and_test)* + self.DefaultNodeVisit(node) + _IncreasePenalty(node, OR_TEST) + index = 1 + while index + 1 < len(node.children): + if style.Get('SPLIT_BEFORE_LOGICAL_OPERATOR'): + _DecrementSplitPenalty( + pytree_utils.FirstLeafNode(node.children[index]), OR_TEST) + else: + _DecrementSplitPenalty( + pytree_utils.FirstLeafNode(node.children[index + 1]), OR_TEST) + index += 2 + + def Visit_and_test(self, node): # pylint: disable=invalid-name + # and_test ::= not_test ('and' not_test)* + self.DefaultNodeVisit(node) + _IncreasePenalty(node, AND_TEST) + index = 1 + while index + 1 < len(node.children): + if style.Get('SPLIT_BEFORE_LOGICAL_OPERATOR'): + _DecrementSplitPenalty( + pytree_utils.FirstLeafNode(node.children[index]), AND_TEST) + else: + _DecrementSplitPenalty( + pytree_utils.FirstLeafNode(node.children[index + 1]), AND_TEST) + index += 2 + + def Visit_not_test(self, node): # pylint: disable=invalid-name + # not_test ::= 'not' not_test | comparison + self.DefaultNodeVisit(node) + _IncreasePenalty(node, NOT_TEST) + + def Visit_comparison(self, node): # pylint: disable=invalid-name + # comparison ::= expr (comp_op expr)* + self.DefaultNodeVisit(node) + if len(node.children) == 3 and _StronglyConnectedCompOp(node): + _IncreasePenalty(node.children[1], VERY_STRONGLY_CONNECTED) + _SetSplitPenalty( + pytree_utils.FirstLeafNode(node.children[2]), STRONGLY_CONNECTED) + else: + _IncreasePenalty(node, COMPARISON) + + def Visit_star_expr(self, node): # pylint: disable=invalid-name + # star_expr ::= '*' expr + self.DefaultNodeVisit(node) + _IncreasePenalty(node, STAR_EXPR) + + def Visit_expr(self, node): # pylint: disable=invalid-name + # expr ::= xor_expr ('|' xor_expr)* + self.DefaultNodeVisit(node) + _IncreasePenalty(node, EXPR) + _SetBitwiseOperandPenalty(node, '|') + + def Visit_xor_expr(self, node): # pylint: disable=invalid-name + # xor_expr ::= and_expr ('^' and_expr)* + self.DefaultNodeVisit(node) + _IncreasePenalty(node, XOR_EXPR) + _SetBitwiseOperandPenalty(node, '^') + + def Visit_and_expr(self, node): # pylint: disable=invalid-name + # and_expr ::= shift_expr ('&' shift_expr)* + self.DefaultNodeVisit(node) + _IncreasePenalty(node, AND_EXPR) + _SetBitwiseOperandPenalty(node, '&') + + def Visit_shift_expr(self, node): # pylint: disable=invalid-name + # shift_expr ::= arith_expr (('<<'|'>>') arith_expr)* + self.DefaultNodeVisit(node) + _IncreasePenalty(node, SHIFT_EXPR) + + _ARITH_OPS = frozenset({'PLUS', 'MINUS'}) + + def Visit_arith_expr(self, node): # pylint: disable=invalid-name + # arith_expr ::= term (('+'|'-') term)* + self.DefaultNodeVisit(node) + _IncreasePenalty(node, ARITH_EXPR) + _SetExpressionOperandPenalty(node, self._ARITH_OPS) + + _TERM_OPS = frozenset({'STAR', 'AT', 'SLASH', 'PERCENT', 'DOUBLESLASH'}) + + def Visit_term(self, node): # pylint: disable=invalid-name + # term ::= factor (('*'|'@'|'/'|'%'|'//') factor)* + self.DefaultNodeVisit(node) + _IncreasePenalty(node, TERM) + _SetExpressionOperandPenalty(node, self._TERM_OPS) + + def Visit_factor(self, node): # pyline: disable=invalid-name + # factor ::= ('+'|'-'|'~') factor | power + self.DefaultNodeVisit(node) + _IncreasePenalty(node, FACTOR) + + def Visit_atom(self, node): # pylint: disable=invalid-name + # atom ::= ('(' [yield_expr|testlist_gexp] ')' + # '[' [listmaker] ']' | + # '{' [dictsetmaker] '}') + self.DefaultNodeVisit(node) + if (node.children[0].value == '(' and + not hasattr(node.children[0], 'is_pseudo')): + if node.children[-1].value == ')': + if pytree_utils.NodeName(node.parent) == 'if_stmt': + _SetSplitPenalty(node.children[-1], STRONGLY_CONNECTED) + else: + if len(node.children) > 2: + _SetSplitPenalty(pytree_utils.FirstLeafNode(node.children[1]), EXPR) + _SetSplitPenalty(node.children[-1], ATOM) + elif node.children[0].value in '[{' and len(node.children) == 2: + # Keep empty containers together if we can. + _SetUnbreakable(node.children[-1]) + + def Visit_testlist_gexp(self, node): # pylint: disable=invalid-name + self.DefaultNodeVisit(node) + prev_was_comma = False + for child in node.children: + if isinstance(child, pytree.Leaf) and child.value == ',': + _SetUnbreakable(child) + prev_was_comma = True + else: + if prev_was_comma: + _SetSplitPenalty(pytree_utils.FirstLeafNode(child), TOGETHER) + prev_was_comma = False + + +def _SetUnbreakable(node): + """Set an UNBREAKABLE penalty annotation for the given node.""" + _RecAnnotate(node, pytree_utils.Annotation.SPLIT_PENALTY, UNBREAKABLE) + + +def _SetStronglyConnected(*nodes): + """Set a STRONGLY_CONNECTED penalty annotation for the given nodes.""" + for node in nodes: + _RecAnnotate(node, pytree_utils.Annotation.SPLIT_PENALTY, + STRONGLY_CONNECTED) + + +def _SetExpressionPenalty(node, penalty): + """Set a penalty annotation on children nodes.""" + + def RecExpression(node, first_child_leaf): + if node is first_child_leaf: + return + + if isinstance(node, pytree.Leaf): + if node.value in {'(', 'for', 'if'}: + return + penalty_annotation = pytree_utils.GetNodeAnnotation( + node, pytree_utils.Annotation.SPLIT_PENALTY, default=0) + if penalty_annotation < penalty: + _SetSplitPenalty(node, penalty) + else: + for child in node.children: + RecExpression(child, first_child_leaf) + + RecExpression(node, pytree_utils.FirstLeafNode(node)) + + +def _SetBitwiseOperandPenalty(node, op): + for index in py3compat.range(1, len(node.children) - 1): + child = node.children[index] + if isinstance(child, pytree.Leaf) and child.value == op: + if style.Get('SPLIT_BEFORE_BITWISE_OPERATOR'): + _SetSplitPenalty(child, style.Get('SPLIT_PENALTY_BITWISE_OPERATOR')) + else: + _SetSplitPenalty( + pytree_utils.FirstLeafNode(node.children[index + 1]), + style.Get('SPLIT_PENALTY_BITWISE_OPERATOR')) + + +def _SetExpressionOperandPenalty(node, ops): + for index in py3compat.range(1, len(node.children) - 1): + child = node.children[index] + if pytree_utils.NodeName(child) in ops: + if style.Get('SPLIT_BEFORE_ARITHMETIC_OPERATOR'): + _SetSplitPenalty(child, style.Get('SPLIT_PENALTY_ARITHMETIC_OPERATOR')) + else: + _SetSplitPenalty( + pytree_utils.FirstLeafNode(node.children[index + 1]), + style.Get('SPLIT_PENALTY_ARITHMETIC_OPERATOR')) + + +def _IncreasePenalty(node, amt): + """Increase a penalty annotation on children nodes.""" + + def RecExpression(node, first_child_leaf): + if node is first_child_leaf: + return + + if isinstance(node, pytree.Leaf): + if node.value in {'(', 'for'}: + return + penalty = pytree_utils.GetNodeAnnotation( + node, pytree_utils.Annotation.SPLIT_PENALTY, default=0) + _SetSplitPenalty(node, penalty + amt) + else: + for child in node.children: + RecExpression(child, first_child_leaf) + + RecExpression(node, pytree_utils.FirstLeafNode(node)) + + +def _RecAnnotate(tree, annotate_name, annotate_value): + """Recursively set the given annotation on all leafs of the subtree. + + Takes care to only increase the penalty. If the node already has a higher + or equal penalty associated with it, this is a no-op. + + Args: + tree: subtree to annotate + annotate_name: name of the annotation to set + annotate_value: value of the annotation to set + """ + for child in tree.children: + _RecAnnotate(child, annotate_name, annotate_value) + if isinstance(tree, pytree.Leaf): + cur_annotate = pytree_utils.GetNodeAnnotation( + tree, annotate_name, default=0) + if cur_annotate < annotate_value: + pytree_utils.SetNodeAnnotation(tree, annotate_name, annotate_value) + + +def _StronglyConnectedCompOp(op): + if (len(op.children[1].children) == 2 and + pytree_utils.NodeName(op.children[1]) == 'comp_op'): + if (pytree_utils.FirstLeafNode(op.children[1]).value == 'not' and + pytree_utils.LastLeafNode(op.children[1]).value == 'in'): + return True + if (pytree_utils.FirstLeafNode(op.children[1]).value == 'is' and + pytree_utils.LastLeafNode(op.children[1]).value == 'not'): + return True + if (isinstance(op.children[1], pytree.Leaf) and + op.children[1].value in {'==', 'in'}): + return True + return False + + +def _DecrementSplitPenalty(node, amt): + penalty = pytree_utils.GetNodeAnnotation( + node, pytree_utils.Annotation.SPLIT_PENALTY, default=amt) + penalty = penalty - amt if amt < penalty else 0 + _SetSplitPenalty(node, penalty) + + +def _SetSplitPenalty(node, penalty): + pytree_utils.SetNodeAnnotation(node, pytree_utils.Annotation.SPLIT_PENALTY, + penalty) diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/style.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/style.py new file mode 100644 index 00000000..6bd2372f --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/style.py @@ -0,0 +1,849 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Python formatting style settings.""" + +import os +import re +import textwrap + +from yapf.yapflib import errors +from yapf.yapflib import py3compat + + +class StyleConfigError(errors.YapfError): + """Raised when there's a problem reading the style configuration.""" + pass + + +def Get(setting_name): + """Get a style setting.""" + return _style[setting_name] + + +def GetOrDefault(setting_name, default_value): + """Get a style setting or default value if the setting does not exist.""" + return _style.get(setting_name, default_value) + + +def Help(): + """Return dict mapping style names to help strings.""" + return _STYLE_HELP + + +def SetGlobalStyle(style): + """Set a style dict.""" + global _style + global _GLOBAL_STYLE_FACTORY + factory = _GetStyleFactory(style) + if factory: + _GLOBAL_STYLE_FACTORY = factory + _style = style + + +_STYLE_HELP = dict( + ALIGN_CLOSING_BRACKET_WITH_VISUAL_INDENT=textwrap.dedent("""\ + Align closing bracket with visual indentation."""), + ALLOW_MULTILINE_LAMBDAS=textwrap.dedent("""\ + Allow lambdas to be formatted on more than one line."""), + ALLOW_MULTILINE_DICTIONARY_KEYS=textwrap.dedent("""\ + Allow dictionary keys to exist on multiple lines. For example: + + x = { + ('this is the first element of a tuple', + 'this is the second element of a tuple'): + value, + }"""), + ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS=textwrap.dedent("""\ + Allow splitting before a default / named assignment in an argument list. + """), + ALLOW_SPLIT_BEFORE_DICT_VALUE=textwrap.dedent("""\ + Allow splits before the dictionary value."""), + ARITHMETIC_PRECEDENCE_INDICATION=textwrap.dedent("""\ + Let spacing indicate operator precedence. For example: + + a = 1 * 2 + 3 / 4 + b = 1 / 2 - 3 * 4 + c = (1 + 2) * (3 - 4) + d = (1 - 2) / (3 + 4) + e = 1 * 2 - 3 + f = 1 + 2 + 3 + 4 + + will be formatted as follows to indicate precedence: + + a = 1*2 + 3/4 + b = 1/2 - 3*4 + c = (1+2) * (3-4) + d = (1-2) / (3+4) + e = 1*2 - 3 + f = 1 + 2 + 3 + 4 + + """), + BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF=textwrap.dedent("""\ + Insert a blank line before a 'def' or 'class' immediately nested + within another 'def' or 'class'. For example: + + class Foo: + # <------ this blank line + def method(): + ..."""), + BLANK_LINE_BEFORE_CLASS_DOCSTRING=textwrap.dedent("""\ + Insert a blank line before a class-level docstring."""), + BLANK_LINE_BEFORE_MODULE_DOCSTRING=textwrap.dedent("""\ + Insert a blank line before a module docstring."""), + BLANK_LINES_AROUND_TOP_LEVEL_DEFINITION=textwrap.dedent("""\ + Number of blank lines surrounding top-level function and class + definitions."""), + BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES=textwrap.dedent("""\ + Number of blank lines between top-level imports and variable + definitions."""), + COALESCE_BRACKETS=textwrap.dedent("""\ + Do not split consecutive brackets. Only relevant when + dedent_closing_brackets is set. For example: + + call_func_that_takes_a_dict( + { + 'key1': 'value1', + 'key2': 'value2', + } + ) + + would reformat to: + + call_func_that_takes_a_dict({ + 'key1': 'value1', + 'key2': 'value2', + })"""), + COLUMN_LIMIT=textwrap.dedent("""\ + The column limit."""), + CONTINUATION_ALIGN_STYLE=textwrap.dedent("""\ + The style for continuation alignment. Possible values are: + + - SPACE: Use spaces for continuation alignment. This is default behavior. + - FIXED: Use fixed number (CONTINUATION_INDENT_WIDTH) of columns + (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs or + CONTINUATION_INDENT_WIDTH spaces) for continuation alignment. + - VALIGN-RIGHT: Vertically align continuation lines to multiple of + INDENT_WIDTH columns. Slightly right (one tab or a few spaces) if + cannot vertically align continuation lines with indent characters."""), + CONTINUATION_INDENT_WIDTH=textwrap.dedent("""\ + Indent width used for line continuations."""), + DEDENT_CLOSING_BRACKETS=textwrap.dedent("""\ + Put closing brackets on a separate line, dedented, if the bracketed + expression can't fit in a single line. Applies to all kinds of brackets, + including function definitions and calls. For example: + + config = { + 'key1': 'value1', + 'key2': 'value2', + } # <--- this bracket is dedented and on a separate line + + time_series = self.remote_client.query_entity_counters( + entity='dev3246.region1', + key='dns.query_latency_tcp', + transform=Transformation.AVERAGE(window=timedelta(seconds=60)), + start_ts=now()-timedelta(days=3), + end_ts=now(), + ) # <--- this bracket is dedented and on a separate line + """), + DISABLE_ENDING_COMMA_HEURISTIC=textwrap.dedent("""\ + Disable the heuristic which places each list element on a separate line + if the list is comma-terminated."""), + EACH_DICT_ENTRY_ON_SEPARATE_LINE=textwrap.dedent("""\ + Place each dictionary entry onto its own line."""), + FORCE_MULTILINE_DICT=textwrap.dedent("""\ + Require multiline dictionary even if it would normally fit on one line. + For example: + + config = { + 'key1': 'value1' + }"""), + I18N_COMMENT=textwrap.dedent("""\ + The regex for an i18n comment. The presence of this comment stops + reformatting of that line, because the comments are required to be + next to the string they translate."""), + I18N_FUNCTION_CALL=textwrap.dedent("""\ + The i18n function call names. The presence of this function stops + reformattting on that line, because the string it has cannot be moved + away from the i18n comment."""), + INDENT_CLOSING_BRACKETS=textwrap.dedent("""\ + Put closing brackets on a separate line, indented, if the bracketed + expression can't fit in a single line. Applies to all kinds of brackets, + including function definitions and calls. For example: + + config = { + 'key1': 'value1', + 'key2': 'value2', + } # <--- this bracket is indented and on a separate line + + time_series = self.remote_client.query_entity_counters( + entity='dev3246.region1', + key='dns.query_latency_tcp', + transform=Transformation.AVERAGE(window=timedelta(seconds=60)), + start_ts=now()-timedelta(days=3), + end_ts=now(), + ) # <--- this bracket is indented and on a separate line + """), + INDENT_DICTIONARY_VALUE=textwrap.dedent("""\ + Indent the dictionary value if it cannot fit on the same line as the + dictionary key. For example: + + config = { + 'key1': + 'value1', + 'key2': value1 + + value2, + } + """), + INDENT_WIDTH=textwrap.dedent("""\ + The number of columns to use for indentation."""), + INDENT_BLANK_LINES=textwrap.dedent("""\ + Indent blank lines."""), + JOIN_MULTIPLE_LINES=textwrap.dedent("""\ + Join short lines into one line. E.g., single line 'if' statements."""), + NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS=textwrap.dedent("""\ + Do not include spaces around selected binary operators. For example: + + 1 + 2 * 3 - 4 / 5 + + will be formatted as follows when configured with "*,/": + + 1 + 2*3 - 4/5 + """), + SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET=textwrap.dedent("""\ + Insert a space between the ending comma and closing bracket of a list, + etc."""), + SPACE_INSIDE_BRACKETS=textwrap.dedent("""\ + Use spaces inside brackets, braces, and parentheses. For example: + + method_call( 1 ) + my_dict[ 3 ][ 1 ][ get_index( *args, **kwargs ) ] + my_set = { 1, 2, 3 } + """), + SPACES_AROUND_POWER_OPERATOR=textwrap.dedent("""\ + Use spaces around the power operator."""), + SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN=textwrap.dedent("""\ + Use spaces around default or named assigns."""), + SPACES_AROUND_DICT_DELIMITERS=textwrap.dedent("""\ + Adds a space after the opening '{' and before the ending '}' dict delimiters. + + {1: 2} + + will be formatted as: + + { 1: 2 } + """), + SPACES_AROUND_LIST_DELIMITERS=textwrap.dedent("""\ + Adds a space after the opening '[' and before the ending ']' list delimiters. + + [1, 2] + + will be formatted as: + + [ 1, 2 ] + """), + SPACES_AROUND_SUBSCRIPT_COLON=textwrap.dedent("""\ + Use spaces around the subscript / slice operator. For example: + + my_list[1 : 10 : 2] + """), + SPACES_AROUND_TUPLE_DELIMITERS=textwrap.dedent("""\ + Adds a space after the opening '(' and before the ending ')' tuple delimiters. + + (1, 2, 3) + + will be formatted as: + + ( 1, 2, 3 ) + """), + SPACES_BEFORE_COMMENT=textwrap.dedent("""\ + The number of spaces required before a trailing comment. + This can be a single value (representing the number of spaces + before each trailing comment) or list of values (representing + alignment column values; trailing comments within a block will + be aligned to the first column value that is greater than the maximum + line length within the block). For example: + + With spaces_before_comment=5: + + 1 + 1 # Adding values + + will be formatted as: + + 1 + 1 # Adding values <-- 5 spaces between the end of the statement and comment + + With spaces_before_comment=15, 20: + + 1 + 1 # Adding values + two + two # More adding + + longer_statement # This is a longer statement + short # This is a shorter statement + + a_very_long_statement_that_extends_beyond_the_final_column # Comment + short # This is a shorter statement + + will be formatted as: + + 1 + 1 # Adding values <-- end of line comments in block aligned to col 15 + two + two # More adding + + longer_statement # This is a longer statement <-- end of line comments in block aligned to col 20 + short # This is a shorter statement + + a_very_long_statement_that_extends_beyond_the_final_column # Comment <-- the end of line comments are aligned based on the line length + short # This is a shorter statement + + """), + SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED=textwrap.dedent("""\ + Split before arguments if the argument list is terminated by a + comma."""), + SPLIT_ALL_COMMA_SEPARATED_VALUES=textwrap.dedent("""\ + Split before arguments"""), + SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES=textwrap.dedent("""\ + Split before arguments, but do not split all subexpressions recursively + (unless needed)."""), + SPLIT_BEFORE_ARITHMETIC_OPERATOR=textwrap.dedent("""\ + Set to True to prefer splitting before '+', '-', '*', '/', '//', or '@' + rather than after."""), + SPLIT_BEFORE_BITWISE_OPERATOR=textwrap.dedent("""\ + Set to True to prefer splitting before '&', '|' or '^' rather than + after."""), + SPLIT_BEFORE_CLOSING_BRACKET=textwrap.dedent("""\ + Split before the closing bracket if a list or dict literal doesn't fit on + a single line."""), + SPLIT_BEFORE_DICT_SET_GENERATOR=textwrap.dedent("""\ + Split before a dictionary or set generator (comp_for). For example, note + the split before the 'for': + + foo = { + variable: 'Hello world, have a nice day!' + for variable in bar if variable != 42 + }"""), + SPLIT_BEFORE_DOT=textwrap.dedent("""\ + Split before the '.' if we need to split a longer expression: + + foo = ('This is a really long string: {}, {}, {}, {}'.format(a, b, c, d)) + + would reformat to something like: + + foo = ('This is a really long string: {}, {}, {}, {}' + .format(a, b, c, d)) + """), + SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN=textwrap.dedent("""\ + Split after the opening paren which surrounds an expression if it doesn't + fit on a single line. + """), + SPLIT_BEFORE_FIRST_ARGUMENT=textwrap.dedent("""\ + If an argument / parameter list is going to be split, then split before + the first argument."""), + SPLIT_BEFORE_LOGICAL_OPERATOR=textwrap.dedent("""\ + Set to True to prefer splitting before 'and' or 'or' rather than + after."""), + SPLIT_BEFORE_NAMED_ASSIGNS=textwrap.dedent("""\ + Split named assignments onto individual lines."""), + SPLIT_COMPLEX_COMPREHENSION=textwrap.dedent("""\ + Set to True to split list comprehensions and generators that have + non-trivial expressions and multiple clauses before each of these + clauses. For example: + + result = [ + a_long_var + 100 for a_long_var in xrange(1000) + if a_long_var % 10] + + would reformat to something like: + + result = [ + a_long_var + 100 + for a_long_var in xrange(1000) + if a_long_var % 10] + """), + SPLIT_PENALTY_AFTER_OPENING_BRACKET=textwrap.dedent("""\ + The penalty for splitting right after the opening bracket."""), + SPLIT_PENALTY_AFTER_UNARY_OPERATOR=textwrap.dedent("""\ + The penalty for splitting the line after a unary operator."""), + SPLIT_PENALTY_ARITHMETIC_OPERATOR=textwrap.dedent("""\ + The penalty of splitting the line around the '+', '-', '*', '/', '//', + ``%``, and '@' operators."""), + SPLIT_PENALTY_BEFORE_IF_EXPR=textwrap.dedent("""\ + The penalty for splitting right before an if expression."""), + SPLIT_PENALTY_BITWISE_OPERATOR=textwrap.dedent("""\ + The penalty of splitting the line around the '&', '|', and '^' + operators."""), + SPLIT_PENALTY_COMPREHENSION=textwrap.dedent("""\ + The penalty for splitting a list comprehension or generator + expression."""), + SPLIT_PENALTY_EXCESS_CHARACTER=textwrap.dedent("""\ + The penalty for characters over the column limit."""), + SPLIT_PENALTY_FOR_ADDED_LINE_SPLIT=textwrap.dedent("""\ + The penalty incurred by adding a line split to the unwrapped line. The + more line splits added the higher the penalty."""), + SPLIT_PENALTY_IMPORT_NAMES=textwrap.dedent("""\ + The penalty of splitting a list of "import as" names. For example: + + from a_very_long_or_indented_module_name_yada_yad import (long_argument_1, + long_argument_2, + long_argument_3) + + would reformat to something like: + + from a_very_long_or_indented_module_name_yada_yad import ( + long_argument_1, long_argument_2, long_argument_3) + """), + SPLIT_PENALTY_LOGICAL_OPERATOR=textwrap.dedent("""\ + The penalty of splitting the line around the 'and' and 'or' + operators."""), + USE_TABS=textwrap.dedent("""\ + Use the Tab character for indentation."""), + # BASED_ON_STYLE='Which predefined style this style is based on', +) + + +def CreatePEP8Style(): + """Create the PEP8 formatting style.""" + return dict( + ALIGN_CLOSING_BRACKET_WITH_VISUAL_INDENT=True, + ALLOW_MULTILINE_LAMBDAS=False, + ALLOW_MULTILINE_DICTIONARY_KEYS=False, + ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS=True, + ALLOW_SPLIT_BEFORE_DICT_VALUE=True, + ARITHMETIC_PRECEDENCE_INDICATION=False, + BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF=False, + BLANK_LINE_BEFORE_CLASS_DOCSTRING=False, + BLANK_LINE_BEFORE_MODULE_DOCSTRING=False, + BLANK_LINES_AROUND_TOP_LEVEL_DEFINITION=2, + BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES=1, + COALESCE_BRACKETS=False, + COLUMN_LIMIT=79, + CONTINUATION_ALIGN_STYLE='SPACE', + CONTINUATION_INDENT_WIDTH=4, + DEDENT_CLOSING_BRACKETS=False, + INDENT_CLOSING_BRACKETS=False, + DISABLE_ENDING_COMMA_HEURISTIC=False, + EACH_DICT_ENTRY_ON_SEPARATE_LINE=True, + FORCE_MULTILINE_DICT=False, + I18N_COMMENT='', + I18N_FUNCTION_CALL='', + INDENT_DICTIONARY_VALUE=False, + INDENT_WIDTH=4, + INDENT_BLANK_LINES=False, + JOIN_MULTIPLE_LINES=True, + NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS=set(), + SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET=True, + SPACE_INSIDE_BRACKETS=False, + SPACES_AROUND_POWER_OPERATOR=False, + SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN=False, + SPACES_AROUND_DICT_DELIMITERS=False, + SPACES_AROUND_LIST_DELIMITERS=False, + SPACES_AROUND_SUBSCRIPT_COLON=False, + SPACES_AROUND_TUPLE_DELIMITERS=False, + SPACES_BEFORE_COMMENT=2, + SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED=False, + SPLIT_ALL_COMMA_SEPARATED_VALUES=False, + SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES=False, + SPLIT_BEFORE_ARITHMETIC_OPERATOR=False, + SPLIT_BEFORE_BITWISE_OPERATOR=True, + SPLIT_BEFORE_CLOSING_BRACKET=True, + SPLIT_BEFORE_DICT_SET_GENERATOR=True, + SPLIT_BEFORE_DOT=False, + SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN=False, + SPLIT_BEFORE_FIRST_ARGUMENT=False, + SPLIT_BEFORE_LOGICAL_OPERATOR=True, + SPLIT_BEFORE_NAMED_ASSIGNS=True, + SPLIT_COMPLEX_COMPREHENSION=False, + SPLIT_PENALTY_AFTER_OPENING_BRACKET=300, + SPLIT_PENALTY_AFTER_UNARY_OPERATOR=10000, + SPLIT_PENALTY_ARITHMETIC_OPERATOR=300, + SPLIT_PENALTY_BEFORE_IF_EXPR=0, + SPLIT_PENALTY_BITWISE_OPERATOR=300, + SPLIT_PENALTY_COMPREHENSION=80, + SPLIT_PENALTY_EXCESS_CHARACTER=7000, + SPLIT_PENALTY_FOR_ADDED_LINE_SPLIT=30, + SPLIT_PENALTY_IMPORT_NAMES=0, + SPLIT_PENALTY_LOGICAL_OPERATOR=300, + USE_TABS=False, + ) + + +def CreateGoogleStyle(): + """Create the Google formatting style.""" + style = CreatePEP8Style() + style['ALIGN_CLOSING_BRACKET_WITH_VISUAL_INDENT'] = False + style['BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF'] = True + style['COLUMN_LIMIT'] = 80 + style['INDENT_DICTIONARY_VALUE'] = True + style['INDENT_WIDTH'] = 4 + style['I18N_COMMENT'] = r'#\..*' + style['I18N_FUNCTION_CALL'] = ['N_', '_'] + style['JOIN_MULTIPLE_LINES'] = False + style['SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET'] = False + style['SPLIT_BEFORE_BITWISE_OPERATOR'] = False + style['SPLIT_BEFORE_DICT_SET_GENERATOR'] = False + style['SPLIT_BEFORE_LOGICAL_OPERATOR'] = False + style['SPLIT_COMPLEX_COMPREHENSION'] = True + style['SPLIT_PENALTY_COMPREHENSION'] = 2100 + return style + + +def CreateYapfStyle(): + """Create the YAPF formatting style.""" + style = CreateGoogleStyle() + style['ALLOW_MULTILINE_DICTIONARY_KEYS'] = True + style['ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS'] = False + style['INDENT_WIDTH'] = 2 + style['SPLIT_BEFORE_BITWISE_OPERATOR'] = True + style['SPLIT_BEFORE_DOT'] = True + style['SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN'] = True + return style + + +def CreateFacebookStyle(): + """Create the Facebook formatting style.""" + style = CreatePEP8Style() + style['ALIGN_CLOSING_BRACKET_WITH_VISUAL_INDENT'] = False + style['COLUMN_LIMIT'] = 80 + style['DEDENT_CLOSING_BRACKETS'] = True + style['INDENT_CLOSING_BRACKETS'] = False + style['INDENT_DICTIONARY_VALUE'] = True + style['JOIN_MULTIPLE_LINES'] = False + style['SPACES_BEFORE_COMMENT'] = 2 + style['SPLIT_PENALTY_AFTER_OPENING_BRACKET'] = 0 + style['SPLIT_PENALTY_BEFORE_IF_EXPR'] = 30 + style['SPLIT_PENALTY_FOR_ADDED_LINE_SPLIT'] = 30 + style['SPLIT_BEFORE_LOGICAL_OPERATOR'] = False + style['SPLIT_BEFORE_BITWISE_OPERATOR'] = False + return style + + +_STYLE_NAME_TO_FACTORY = dict( + pep8=CreatePEP8Style, + google=CreateGoogleStyle, + facebook=CreateFacebookStyle, + yapf=CreateYapfStyle, +) + +_DEFAULT_STYLE_TO_FACTORY = [ + (CreateFacebookStyle(), CreateFacebookStyle), + (CreateGoogleStyle(), CreateGoogleStyle), + (CreatePEP8Style(), CreatePEP8Style), + (CreateYapfStyle(), CreateYapfStyle), +] + + +def _GetStyleFactory(style): + for def_style, factory in _DEFAULT_STYLE_TO_FACTORY: + if style == def_style: + return factory + return None + + +def _ContinuationAlignStyleStringConverter(s): + """Option value converter for a continuation align style string.""" + accepted_styles = ('SPACE', 'FIXED', 'VALIGN-RIGHT') + if s: + r = s.strip('"\'').replace('_', '-').upper() + if r not in accepted_styles: + raise ValueError('unknown continuation align style: %r' % (s,)) + else: + r = accepted_styles[0] + return r + + +def _StringListConverter(s): + """Option value converter for a comma-separated list of strings.""" + return [part.strip() for part in s.split(',')] + + +def _StringSetConverter(s): + """Option value converter for a comma-separated set of strings.""" + if len(s) > 2 and s[0] in '"\'': + s = s[1:-1] + return set(part.strip() for part in s.split(',')) + + +def _BoolConverter(s): + """Option value converter for a boolean.""" + return py3compat.CONFIGPARSER_BOOLEAN_STATES[s.lower()] + + +def _IntListConverter(s): + """Option value converter for a comma-separated list of integers.""" + s = s.strip() + if s.startswith('[') and s.endswith(']'): + s = s[1:-1] + + return [int(part.strip()) for part in s.split(',') if part.strip()] + + +def _IntOrIntListConverter(s): + """Option value converter for an integer or list of integers.""" + if len(s) > 2 and s[0] in '"\'': + s = s[1:-1] + return _IntListConverter(s) if ',' in s else int(s) + + +# Different style options need to have their values interpreted differently when +# read from the config file. This dict maps an option name to a "converter" +# function that accepts the string read for the option's value from the file and +# returns it wrapper in actual Python type that's going to be meaningful to +# yapf. +# +# Note: this dict has to map all the supported style options. +_STYLE_OPTION_VALUE_CONVERTER = dict( + ALIGN_CLOSING_BRACKET_WITH_VISUAL_INDENT=_BoolConverter, + ALLOW_MULTILINE_LAMBDAS=_BoolConverter, + ALLOW_MULTILINE_DICTIONARY_KEYS=_BoolConverter, + ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS=_BoolConverter, + ALLOW_SPLIT_BEFORE_DICT_VALUE=_BoolConverter, + ARITHMETIC_PRECEDENCE_INDICATION=_BoolConverter, + BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF=_BoolConverter, + BLANK_LINE_BEFORE_CLASS_DOCSTRING=_BoolConverter, + BLANK_LINE_BEFORE_MODULE_DOCSTRING=_BoolConverter, + BLANK_LINES_AROUND_TOP_LEVEL_DEFINITION=int, + BLANK_LINES_BETWEEN_TOP_LEVEL_IMPORTS_AND_VARIABLES=int, + COALESCE_BRACKETS=_BoolConverter, + COLUMN_LIMIT=int, + CONTINUATION_ALIGN_STYLE=_ContinuationAlignStyleStringConverter, + CONTINUATION_INDENT_WIDTH=int, + DEDENT_CLOSING_BRACKETS=_BoolConverter, + INDENT_CLOSING_BRACKETS=_BoolConverter, + DISABLE_ENDING_COMMA_HEURISTIC=_BoolConverter, + EACH_DICT_ENTRY_ON_SEPARATE_LINE=_BoolConverter, + FORCE_MULTILINE_DICT=_BoolConverter, + I18N_COMMENT=str, + I18N_FUNCTION_CALL=_StringListConverter, + INDENT_DICTIONARY_VALUE=_BoolConverter, + INDENT_WIDTH=int, + INDENT_BLANK_LINES=_BoolConverter, + JOIN_MULTIPLE_LINES=_BoolConverter, + NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS=_StringSetConverter, + SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET=_BoolConverter, + SPACE_INSIDE_BRACKETS=_BoolConverter, + SPACES_AROUND_POWER_OPERATOR=_BoolConverter, + SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN=_BoolConverter, + SPACES_AROUND_DICT_DELIMITERS=_BoolConverter, + SPACES_AROUND_LIST_DELIMITERS=_BoolConverter, + SPACES_AROUND_SUBSCRIPT_COLON=_BoolConverter, + SPACES_AROUND_TUPLE_DELIMITERS=_BoolConverter, + SPACES_BEFORE_COMMENT=_IntOrIntListConverter, + SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED=_BoolConverter, + SPLIT_ALL_COMMA_SEPARATED_VALUES=_BoolConverter, + SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES=_BoolConverter, + SPLIT_BEFORE_ARITHMETIC_OPERATOR=_BoolConverter, + SPLIT_BEFORE_BITWISE_OPERATOR=_BoolConverter, + SPLIT_BEFORE_CLOSING_BRACKET=_BoolConverter, + SPLIT_BEFORE_DICT_SET_GENERATOR=_BoolConverter, + SPLIT_BEFORE_DOT=_BoolConverter, + SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN=_BoolConverter, + SPLIT_BEFORE_FIRST_ARGUMENT=_BoolConverter, + SPLIT_BEFORE_LOGICAL_OPERATOR=_BoolConverter, + SPLIT_BEFORE_NAMED_ASSIGNS=_BoolConverter, + SPLIT_COMPLEX_COMPREHENSION=_BoolConverter, + SPLIT_PENALTY_AFTER_OPENING_BRACKET=int, + SPLIT_PENALTY_AFTER_UNARY_OPERATOR=int, + SPLIT_PENALTY_ARITHMETIC_OPERATOR=int, + SPLIT_PENALTY_BEFORE_IF_EXPR=int, + SPLIT_PENALTY_BITWISE_OPERATOR=int, + SPLIT_PENALTY_COMPREHENSION=int, + SPLIT_PENALTY_EXCESS_CHARACTER=int, + SPLIT_PENALTY_FOR_ADDED_LINE_SPLIT=int, + SPLIT_PENALTY_IMPORT_NAMES=int, + SPLIT_PENALTY_LOGICAL_OPERATOR=int, + USE_TABS=_BoolConverter, +) + + +def CreateStyleFromConfig(style_config): + """Create a style dict from the given config. + + Arguments: + style_config: either a style name or a file name. The file is expected to + contain settings. It can have a special BASED_ON_STYLE setting naming the + style which it derives from. If no such setting is found, it derives from + the default style. When style_config is None, the _GLOBAL_STYLE_FACTORY + config is created. + + Returns: + A style dict. + + Raises: + StyleConfigError: if an unknown style option was encountered. + """ + + def GlobalStyles(): + for style, _ in _DEFAULT_STYLE_TO_FACTORY: + yield style + + def_style = False + if style_config is None: + for style in GlobalStyles(): + if _style == style: + def_style = True + break + if not def_style: + return _style + return _GLOBAL_STYLE_FACTORY() + + if isinstance(style_config, dict): + config = _CreateConfigParserFromConfigDict(style_config) + elif isinstance(style_config, py3compat.basestring): + style_factory = _STYLE_NAME_TO_FACTORY.get(style_config.lower()) + if style_factory is not None: + return style_factory() + if style_config.startswith('{'): + # Most likely a style specification from the command line. + config = _CreateConfigParserFromConfigString(style_config) + else: + # Unknown config name: assume it's a file name then. + config = _CreateConfigParserFromConfigFile(style_config) + return _CreateStyleFromConfigParser(config) + + +def _CreateConfigParserFromConfigDict(config_dict): + config = py3compat.ConfigParser() + config.add_section('style') + for key, value in config_dict.items(): + config.set('style', key, str(value)) + return config + + +def _CreateConfigParserFromConfigString(config_string): + """Given a config string from the command line, return a config parser.""" + if config_string[0] != '{' or config_string[-1] != '}': + raise StyleConfigError( + "Invalid style dict syntax: '{}'.".format(config_string)) + config = py3compat.ConfigParser() + config.add_section('style') + for key, value, _ in re.findall( + r'([a-zA-Z0-9_]+)\s*[:=]\s*' + r'(?:' + r'((?P[\'"]).*?(?P=quote)|' + r'[a-zA-Z0-9_]+)' + r')', config_string): # yapf: disable + config.set('style', key, value) + return config + + +def _CreateConfigParserFromConfigFile(config_filename): + """Read the file and return a ConfigParser object.""" + if not os.path.exists(config_filename): + # Provide a more meaningful error here. + raise StyleConfigError( + '"{0}" is not a valid style or file path'.format(config_filename)) + with open(config_filename) as style_file: + config = py3compat.ConfigParser() + if config_filename.endswith(PYPROJECT_TOML): + try: + import toml + except ImportError: + raise errors.YapfError( + "toml package is needed for using pyproject.toml as a configuration file" + ) + + pyproject_toml = toml.load(style_file) + style_dict = pyproject_toml.get("tool", {}).get("yapf", None) + if style_dict is None: + raise StyleConfigError( + 'Unable to find section [tool.yapf] in {0}'.format(config_filename)) + config.add_section('style') + for k, v in style_dict.items(): + config.set('style', k, str(v)) + return config + + config.read_file(style_file) + if config_filename.endswith(SETUP_CONFIG): + if not config.has_section('yapf'): + raise StyleConfigError( + 'Unable to find section [yapf] in {0}'.format(config_filename)) + return config + + if config_filename.endswith(LOCAL_STYLE): + if not config.has_section('style'): + raise StyleConfigError( + 'Unable to find section [style] in {0}'.format(config_filename)) + return config + + if not config.has_section('style'): + raise StyleConfigError( + 'Unable to find section [style] in {0}'.format(config_filename)) + return config + + +def _CreateStyleFromConfigParser(config): + """Create a style dict from a configuration file. + + Arguments: + config: a ConfigParser object. + + Returns: + A style dict. + + Raises: + StyleConfigError: if an unknown style option was encountered. + """ + # Initialize the base style. + section = 'yapf' if config.has_section('yapf') else 'style' + if config.has_option('style', 'based_on_style'): + based_on = config.get('style', 'based_on_style').lower() + base_style = _STYLE_NAME_TO_FACTORY[based_on]() + elif config.has_option('yapf', 'based_on_style'): + based_on = config.get('yapf', 'based_on_style').lower() + base_style = _STYLE_NAME_TO_FACTORY[based_on]() + else: + base_style = _GLOBAL_STYLE_FACTORY() + + # Read all options specified in the file and update the style. + for option, value in config.items(section): + if option.lower() == 'based_on_style': + # Now skip this one - we've already handled it and it's not one of the + # recognized style options. + continue + option = option.upper() + if option not in _STYLE_OPTION_VALUE_CONVERTER: + raise StyleConfigError('Unknown style option "{0}"'.format(option)) + try: + base_style[option] = _STYLE_OPTION_VALUE_CONVERTER[option](value) + except ValueError: + raise StyleConfigError("'{}' is not a valid setting for {}.".format( + value, option)) + return base_style + + +# The default style - used if yapf is not invoked without specifically +# requesting a formatting style. +DEFAULT_STYLE = 'pep8' +DEFAULT_STYLE_FACTORY = CreatePEP8Style +_GLOBAL_STYLE_FACTORY = CreatePEP8Style + +# The name of the file to use for global style definition. +GLOBAL_STYLE = ( + os.path.join( + os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config'), 'yapf', + 'style')) + +# The name of the file to use for directory-local style definition. +LOCAL_STYLE = '.style.yapf' + +# Alternative place for directory-local style definition. Style should be +# specified in the '[yapf]' section. +SETUP_CONFIG = 'setup.cfg' + +# Style definition by local pyproject.toml file. Style should be specified +# in the '[tool.yapf]' section. +PYPROJECT_TOML = 'pyproject.toml' + +# TODO(eliben): For now we're preserving the global presence of a style dict. +# Refactor this so that the style is passed around through yapf rather than +# being global. +_style = None +SetGlobalStyle(_GLOBAL_STYLE_FACTORY()) diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/subtype_assigner.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/subtype_assigner.py new file mode 100644 index 00000000..0fa2d966 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/subtype_assigner.py @@ -0,0 +1,509 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Subtype assigner for lib2to3 trees. + +This module assigns extra type information to the lib2to3 trees. This +information is more specific than whether something is an operator or an +identifier. For instance, it can specify if a node in the tree is part of a +subscript. + + AssignSubtypes(): the main function exported by this module. + +Annotations: + subtype: The subtype of a pytree token. See 'format_token' module for a list + of subtypes. +""" + +from lib2to3 import pytree +from lib2to3.pgen2 import token +from lib2to3.pygram import python_symbols as syms + +from yapf.yapflib import format_token +from yapf.yapflib import pytree_utils +from yapf.yapflib import pytree_visitor +from yapf.yapflib import style + + +def AssignSubtypes(tree): + """Run the subtype assigner visitor over the tree, modifying it in place. + + Arguments: + tree: the top-level pytree node to annotate with subtypes. + """ + subtype_assigner = _SubtypeAssigner() + subtype_assigner.Visit(tree) + + +# Map tokens in argument lists to their respective subtype. +_ARGLIST_TOKEN_TO_SUBTYPE = { + '=': format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN, + ':': format_token.Subtype.TYPED_NAME, + '*': format_token.Subtype.VARARGS_STAR, + '**': format_token.Subtype.KWARGS_STAR_STAR, +} + + +class _SubtypeAssigner(pytree_visitor.PyTreeVisitor): + """_SubtypeAssigner - see file-level docstring for detailed description. + + The subtype is added as an annotation to the pytree token. + """ + + def Visit_dictsetmaker(self, node): # pylint: disable=invalid-name + # dictsetmaker ::= (test ':' test (comp_for | + # (',' test ':' test)* [','])) | + # (test (comp_for | (',' test)* [','])) + for child in node.children: + self.Visit(child) + + comp_for = False + dict_maker = False + + for child in node.children: + if pytree_utils.NodeName(child) == 'comp_for': + comp_for = True + _AppendFirstLeafTokenSubtype(child, + format_token.Subtype.DICT_SET_GENERATOR) + elif pytree_utils.NodeName(child) in ('COLON', 'DOUBLESTAR'): + dict_maker = True + + if not comp_for and dict_maker: + last_was_colon = False + unpacking = False + for child in node.children: + if pytree_utils.NodeName(child) == 'DOUBLESTAR': + _AppendFirstLeafTokenSubtype(child, + format_token.Subtype.KWARGS_STAR_STAR) + if last_was_colon: + if style.Get('INDENT_DICTIONARY_VALUE'): + _InsertPseudoParentheses(child) + else: + _AppendFirstLeafTokenSubtype(child, + format_token.Subtype.DICTIONARY_VALUE) + elif (isinstance(child, pytree.Node) or + (not child.value.startswith('#') and child.value not in '{:,')): + # Mark the first leaf of a key entry as a DICTIONARY_KEY. We + # normally want to split before them if the dictionary cannot exist + # on a single line. + if not unpacking or pytree_utils.FirstLeafNode(child).value == '**': + _AppendFirstLeafTokenSubtype(child, + format_token.Subtype.DICTIONARY_KEY) + _AppendSubtypeRec(child, format_token.Subtype.DICTIONARY_KEY_PART) + last_was_colon = pytree_utils.NodeName(child) == 'COLON' + if pytree_utils.NodeName(child) == 'DOUBLESTAR': + unpacking = True + elif last_was_colon: + unpacking = False + + def Visit_expr_stmt(self, node): # pylint: disable=invalid-name + # expr_stmt ::= testlist_star_expr (augassign (yield_expr|testlist) + # | ('=' (yield_expr|testlist_star_expr))*) + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value == '=': + _AppendTokenSubtype(child, format_token.Subtype.ASSIGN_OPERATOR) + + def Visit_or_test(self, node): # pylint: disable=invalid-name + # or_test ::= and_test ('or' and_test)* + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value == 'or': + _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR) + + def Visit_and_test(self, node): # pylint: disable=invalid-name + # and_test ::= not_test ('and' not_test)* + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value == 'and': + _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR) + + def Visit_not_test(self, node): # pylint: disable=invalid-name + # not_test ::= 'not' not_test | comparison + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value == 'not': + _AppendTokenSubtype(child, format_token.Subtype.UNARY_OPERATOR) + + def Visit_comparison(self, node): # pylint: disable=invalid-name + # comparison ::= expr (comp_op expr)* + # comp_op ::= '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not in'|'is'|'is not' + for child in node.children: + self.Visit(child) + if (isinstance(child, pytree.Leaf) and + child.value in {'<', '>', '==', '>=', '<=', '<>', '!=', 'in', 'is'}): + _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR) + elif pytree_utils.NodeName(child) == 'comp_op': + for grandchild in child.children: + _AppendTokenSubtype(grandchild, format_token.Subtype.BINARY_OPERATOR) + + def Visit_star_expr(self, node): # pylint: disable=invalid-name + # star_expr ::= '*' expr + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value == '*': + _AppendTokenSubtype(child, format_token.Subtype.UNARY_OPERATOR) + _AppendTokenSubtype(child, format_token.Subtype.VARARGS_STAR) + + def Visit_expr(self, node): # pylint: disable=invalid-name + # expr ::= xor_expr ('|' xor_expr)* + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value == '|': + _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR) + + def Visit_xor_expr(self, node): # pylint: disable=invalid-name + # xor_expr ::= and_expr ('^' and_expr)* + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value == '^': + _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR) + + def Visit_and_expr(self, node): # pylint: disable=invalid-name + # and_expr ::= shift_expr ('&' shift_expr)* + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value == '&': + _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR) + + def Visit_shift_expr(self, node): # pylint: disable=invalid-name + # shift_expr ::= arith_expr (('<<'|'>>') arith_expr)* + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value in {'<<', '>>'}: + _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR) + + def Visit_arith_expr(self, node): # pylint: disable=invalid-name + # arith_expr ::= term (('+'|'-') term)* + for child in node.children: + self.Visit(child) + if _IsAExprOperator(child): + _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR) + _AppendTokenSubtype(child, format_token.Subtype.A_EXPR_OPERATOR) + + if _IsSimpleExpression(node): + for child in node.children: + if _IsAExprOperator(child): + _AppendTokenSubtype(child, format_token.Subtype.SIMPLE_EXPRESSION) + + def Visit_term(self, node): # pylint: disable=invalid-name + # term ::= factor (('*'|'/'|'%'|'//'|'@') factor)* + for child in node.children: + self.Visit(child) + if _IsMExprOperator(child): + _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR) + _AppendTokenSubtype(child, format_token.Subtype.M_EXPR_OPERATOR) + + if _IsSimpleExpression(node): + for child in node.children: + if _IsMExprOperator(child): + _AppendTokenSubtype(child, format_token.Subtype.SIMPLE_EXPRESSION) + + def Visit_factor(self, node): # pylint: disable=invalid-name + # factor ::= ('+'|'-'|'~') factor | power + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value in '+-~': + _AppendTokenSubtype(child, format_token.Subtype.UNARY_OPERATOR) + + def Visit_power(self, node): # pylint: disable=invalid-name + # power ::= atom trailer* ['**' factor] + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value == '**': + _AppendTokenSubtype(child, format_token.Subtype.BINARY_OPERATOR) + + def Visit_trailer(self, node): # pylint: disable=invalid-name + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value in '[]': + _AppendTokenSubtype(child, format_token.Subtype.SUBSCRIPT_BRACKET) + + def Visit_subscript(self, node): # pylint: disable=invalid-name + # subscript ::= test | [test] ':' [test] [sliceop] + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value == ':': + _AppendTokenSubtype(child, format_token.Subtype.SUBSCRIPT_COLON) + + def Visit_sliceop(self, node): # pylint: disable=invalid-name + # sliceop ::= ':' [test] + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value == ':': + _AppendTokenSubtype(child, format_token.Subtype.SUBSCRIPT_COLON) + + def Visit_argument(self, node): # pylint: disable=invalid-name + # argument ::= + # test [comp_for] | test '=' test + self._ProcessArgLists(node) + + def Visit_arglist(self, node): # pylint: disable=invalid-name + # arglist ::= + # (argument ',')* (argument [','] + # | '*' test (',' argument)* [',' '**' test] + # | '**' test) + self._ProcessArgLists(node) + _SetArgListSubtype(node, format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN, + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST) + + def Visit_tname(self, node): # pylint: disable=invalid-name + self._ProcessArgLists(node) + _SetArgListSubtype(node, format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN, + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST) + + def Visit_decorator(self, node): # pylint: disable=invalid-name + # decorator ::= + # '@' dotted_name [ '(' [arglist] ')' ] NEWLINE + for child in node.children: + if isinstance(child, pytree.Leaf) and child.value == '@': + _AppendTokenSubtype(child, subtype=format_token.Subtype.DECORATOR) + self.Visit(child) + + def Visit_funcdef(self, node): # pylint: disable=invalid-name + # funcdef ::= + # 'def' NAME parameters ['->' test] ':' suite + for child in node.children: + if pytree_utils.NodeName(child) == 'NAME' and child.value != 'def': + _AppendTokenSubtype(child, format_token.Subtype.FUNC_DEF) + break + for child in node.children: + self.Visit(child) + + def Visit_parameters(self, node): # pylint: disable=invalid-name + # parameters ::= '(' [typedargslist] ')' + self._ProcessArgLists(node) + if len(node.children) > 2: + _AppendFirstLeafTokenSubtype(node.children[1], + format_token.Subtype.PARAMETER_START) + _AppendLastLeafTokenSubtype(node.children[-2], + format_token.Subtype.PARAMETER_STOP) + + def Visit_typedargslist(self, node): # pylint: disable=invalid-name + # typedargslist ::= + # ((tfpdef ['=' test] ',')* + # ('*' [tname] (',' tname ['=' test])* [',' '**' tname] + # | '**' tname) + # | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) + self._ProcessArgLists(node) + _SetArgListSubtype(node, format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN, + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST) + tname = False + if not node.children: + return + + _AppendFirstLeafTokenSubtype(node.children[0], + format_token.Subtype.PARAMETER_START) + _AppendLastLeafTokenSubtype(node.children[-1], + format_token.Subtype.PARAMETER_STOP) + + i = 1 + tname = pytree_utils.NodeName(node.children[0]) == 'tname' + while i < len(node.children): + prev_child = node.children[i - 1] + child = node.children[i] + i += 1 + + if pytree_utils.NodeName(prev_child) == 'COMMA': + _AppendFirstLeafTokenSubtype(child, + format_token.Subtype.PARAMETER_START) + elif pytree_utils.NodeName(child) == 'COMMA': + _AppendLastLeafTokenSubtype(prev_child, + format_token.Subtype.PARAMETER_STOP) + + if pytree_utils.NodeName(child) == 'tname': + tname = True + _SetArgListSubtype(child, format_token.Subtype.TYPED_NAME, + format_token.Subtype.TYPED_NAME_ARG_LIST) + elif pytree_utils.NodeName(child) == 'COMMA': + tname = False + elif pytree_utils.NodeName(child) == 'EQUAL' and tname: + _AppendTokenSubtype(child, subtype=format_token.Subtype.TYPED_NAME) + tname = False + + def Visit_varargslist(self, node): # pylint: disable=invalid-name + # varargslist ::= + # ((vfpdef ['=' test] ',')* + # ('*' [vname] (',' vname ['=' test])* [',' '**' vname] + # | '**' vname) + # | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) + self._ProcessArgLists(node) + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf) and child.value == '=': + _AppendTokenSubtype(child, format_token.Subtype.VARARGS_LIST) + + def Visit_comp_for(self, node): # pylint: disable=invalid-name + # comp_for ::= 'for' exprlist 'in' testlist_safe [comp_iter] + _AppendSubtypeRec(node, format_token.Subtype.COMP_FOR) + # Mark the previous node as COMP_EXPR unless this is a nested comprehension + # as these will have the outer comprehension as their previous node. + attr = pytree_utils.GetNodeAnnotation(node.parent, + pytree_utils.Annotation.SUBTYPE) + if not attr or format_token.Subtype.COMP_FOR not in attr: + _AppendSubtypeRec(node.parent.children[0], format_token.Subtype.COMP_EXPR) + self.DefaultNodeVisit(node) + + def Visit_old_comp_for(self, node): # pylint: disable=invalid-name + # Python 3.7 + self.Visit_comp_for(node) + + def Visit_comp_if(self, node): # pylint: disable=invalid-name + # comp_if ::= 'if' old_test [comp_iter] + _AppendSubtypeRec(node, format_token.Subtype.COMP_IF) + self.DefaultNodeVisit(node) + + def Visit_old_comp_if(self, node): # pylint: disable=invalid-name + # Python 3.7 + self.Visit_comp_if(node) + + def _ProcessArgLists(self, node): + """Common method for processing argument lists.""" + for child in node.children: + self.Visit(child) + if isinstance(child, pytree.Leaf): + _AppendTokenSubtype( + child, + subtype=_ARGLIST_TOKEN_TO_SUBTYPE.get(child.value, + format_token.Subtype.NONE)) + + +def _SetArgListSubtype(node, node_subtype, list_subtype): + """Set named assign subtype on elements in a arg list.""" + + def HasSubtype(node): + """Return True if the arg list has a named assign subtype.""" + if isinstance(node, pytree.Leaf): + return node_subtype in pytree_utils.GetNodeAnnotation( + node, pytree_utils.Annotation.SUBTYPE, set()) + + for child in node.children: + node_name = pytree_utils.NodeName(child) + if node_name not in {'atom', 'arglist', 'power'}: + if HasSubtype(child): + return True + + return False + + if not HasSubtype(node): + return + + for child in node.children: + node_name = pytree_utils.NodeName(child) + if node_name not in {'atom', 'COMMA'}: + _AppendFirstLeafTokenSubtype(child, list_subtype) + + +def _AppendTokenSubtype(node, subtype): + """Append the token's subtype only if it's not already set.""" + pytree_utils.AppendNodeAnnotation(node, pytree_utils.Annotation.SUBTYPE, + subtype) + + +def _AppendFirstLeafTokenSubtype(node, subtype): + """Append the first leaf token's subtypes.""" + if isinstance(node, pytree.Leaf): + _AppendTokenSubtype(node, subtype) + return + _AppendFirstLeafTokenSubtype(node.children[0], subtype) + + +def _AppendLastLeafTokenSubtype(node, subtype): + """Append the last leaf token's subtypes.""" + if isinstance(node, pytree.Leaf): + _AppendTokenSubtype(node, subtype) + return + _AppendLastLeafTokenSubtype(node.children[-1], subtype) + + +def _AppendSubtypeRec(node, subtype, force=True): + """Append the leafs in the node to the given subtype.""" + if isinstance(node, pytree.Leaf): + _AppendTokenSubtype(node, subtype) + return + for child in node.children: + _AppendSubtypeRec(child, subtype, force=force) + + +def _InsertPseudoParentheses(node): + """Insert pseudo parentheses so that dicts can be formatted correctly.""" + comment_node = None + if isinstance(node, pytree.Node): + if node.children[-1].type == token.COMMENT: + comment_node = node.children[-1].clone() + node.children[-1].remove() + + first = pytree_utils.FirstLeafNode(node) + last = pytree_utils.LastLeafNode(node) + + if first == last and first.type == token.COMMENT: + # A comment was inserted before the value, which is a pytree.Leaf. + # Encompass the dictionary's value into an ATOM node. + last = first.next_sibling + last_clone = last.clone() + new_node = pytree.Node(syms.atom, [first.clone(), last_clone]) + for orig_leaf, clone_leaf in zip(last.leaves(), last_clone.leaves()): + pytree_utils.CopyYapfAnnotations(orig_leaf, clone_leaf) + if hasattr(orig_leaf, 'is_pseudo'): + clone_leaf.is_pseudo = orig_leaf.is_pseudo + + node.replace(new_node) + node = new_node + last.remove() + + first = pytree_utils.FirstLeafNode(node) + last = pytree_utils.LastLeafNode(node) + + lparen = pytree.Leaf( + token.LPAR, u'(', context=('', (first.get_lineno(), first.column - 1))) + last_lineno = last.get_lineno() + if last.type == token.STRING and '\n' in last.value: + last_lineno += last.value.count('\n') + + if last.type == token.STRING and '\n' in last.value: + last_column = len(last.value.split('\n')[-1]) + 1 + else: + last_column = last.column + len(last.value) + 1 + rparen = pytree.Leaf( + token.RPAR, u')', context=('', (last_lineno, last_column))) + + lparen.is_pseudo = True + rparen.is_pseudo = True + + if isinstance(node, pytree.Node): + node.insert_child(0, lparen) + node.append_child(rparen) + if comment_node: + node.append_child(comment_node) + _AppendFirstLeafTokenSubtype(node, format_token.Subtype.DICTIONARY_VALUE) + else: + clone = node.clone() + for orig_leaf, clone_leaf in zip(node.leaves(), clone.leaves()): + pytree_utils.CopyYapfAnnotations(orig_leaf, clone_leaf) + new_node = pytree.Node(syms.atom, [lparen, clone, rparen]) + node.replace(new_node) + _AppendFirstLeafTokenSubtype(clone, format_token.Subtype.DICTIONARY_VALUE) + + +def _IsAExprOperator(node): + return isinstance(node, pytree.Leaf) and node.value in {'+', '-'} + + +def _IsMExprOperator(node): + return isinstance(node, + pytree.Leaf) and node.value in {'*', '/', '%', '//', '@'} + + +def _IsSimpleExpression(node): + """A node with only leafs as children.""" + return all(isinstance(child, pytree.Leaf) for child in node.children) diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/unwrapped_line.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/unwrapped_line.py new file mode 100644 index 00000000..475bd6e0 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/unwrapped_line.py @@ -0,0 +1,673 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""UnwrappedLine primitive for formatting. + +An unwrapped line is the containing data structure produced by the parser. It +collects all nodes (stored in FormatToken objects) that could appear on a +single line if there were no line length restrictions. It's then used by the +parser to perform the wrapping required to comply with the style guide. +""" + +from yapf.yapflib import format_token +from yapf.yapflib import py3compat +from yapf.yapflib import pytree_utils +from yapf.yapflib import split_penalty +from yapf.yapflib import style + +from lib2to3.fixer_util import syms as python_symbols + + +class UnwrappedLine(object): + """Represents a single unwrapped line in the output. + + Attributes: + depth: indentation depth of this line. This is just a numeric value used to + distinguish lines that are more deeply nested than others. It is not the + actual amount of spaces, which is style-dependent. + """ + + def __init__(self, depth, tokens=None): + """Constructor. + + Creates a new unwrapped line with the given depth an initial list of tokens. + Constructs the doubly-linked lists for format tokens using their built-in + next_token and previous_token attributes. + + Arguments: + depth: indentation depth of this line + tokens: initial list of tokens + """ + self.depth = depth + self._tokens = tokens or [] + self.disable = False + + if self._tokens: + # Set up a doubly linked list. + for index, tok in enumerate(self._tokens[1:]): + # Note, 'index' is the index to the previous token. + tok.previous_token = self._tokens[index] + self._tokens[index].next_token = tok + + def CalculateFormattingInformation(self): + """Calculate the split penalty and total length for the tokens.""" + # Say that the first token in the line should have a space before it. This + # means only that if this unwrapped line is joined with a predecessor line, + # then there will be a space between them. + self.first.spaces_required_before = 1 + self.first.total_length = len(self.first.value) + + prev_token = self.first + prev_length = self.first.total_length + for token in self._tokens[1:]: + if (token.spaces_required_before == 0 and + _SpaceRequiredBetween(prev_token, token, self.disable)): + token.spaces_required_before = 1 + + tok_len = len(token.value) if not token.is_pseudo_paren else 0 + + spaces_required_before = token.spaces_required_before + if isinstance(spaces_required_before, list): + assert token.is_comment, token + + # If here, we are looking at a comment token that appears on a line + # with other tokens (but because it is a comment, it is always the last + # token). Rather than specifying the actual number of spaces here, + # hard code a value of 0 and then set it later. This logic only works + # because this comment token is guaranteed to be the last token in the + # list. + spaces_required_before = 0 + + token.total_length = prev_length + tok_len + spaces_required_before + + # The split penalty has to be computed before {must|can}_break_before, + # because these may use it for their decision. + token.split_penalty += _SplitPenalty(prev_token, token) + token.must_break_before = _MustBreakBefore(prev_token, token) + token.can_break_before = ( + token.must_break_before or _CanBreakBefore(prev_token, token)) + + prev_length = token.total_length + prev_token = token + + def Split(self): + """Split the line at semicolons.""" + if not self.has_semicolon or self.disable: + return [self] + + uwlines = [] + uwline = UnwrappedLine(self.depth) + for tok in self._tokens: + if tok.value == ';': + uwlines.append(uwline) + uwline = UnwrappedLine(self.depth) + else: + uwline.AppendToken(tok) + + if uwline.tokens: + uwlines.append(uwline) + + for uwline in uwlines: + pytree_utils.SetNodeAnnotation(uwline.first.node, + pytree_utils.Annotation.MUST_SPLIT, True) + uwline.first.previous_token = None + uwline.last.next_token = None + + return uwlines + + ############################################################################ + # Token Access and Manipulation Methods # + ############################################################################ + + def AppendToken(self, token): + """Append a new FormatToken to the tokens contained in this line.""" + if self._tokens: + token.previous_token = self.last + self.last.next_token = token + self._tokens.append(token) + + def AppendNode(self, node): + """Convenience method to append a pytree node directly. + + Wraps the node with a FormatToken. + + Arguments: + node: the node to append + """ + self.AppendToken(format_token.FormatToken(node)) + + @property + def first(self): + """Returns the first non-whitespace token.""" + return self._tokens[0] + + @property + def last(self): + """Returns the last non-whitespace token.""" + return self._tokens[-1] + + ############################################################################ + # Token -> String Methods # + ############################################################################ + + def AsCode(self, indent_per_depth=2): + """Return a "code" representation of this line. + + The code representation shows how the line would be printed out as code. + + TODO(eliben): for now this is rudimentary for debugging - once we add + formatting capabilities, this method will have other uses (not all tokens + have spaces around them, for example). + + Arguments: + indent_per_depth: how much spaces to indend per depth level. + + Returns: + A string representing the line as code. + """ + indent = ' ' * indent_per_depth * self.depth + tokens_str = ' '.join(tok.value for tok in self._tokens) + return indent + tokens_str + + def __str__(self): # pragma: no cover + return self.AsCode() + + def __repr__(self): # pragma: no cover + tokens_repr = ','.join( + ['{0}({1!r})'.format(tok.name, tok.value) for tok in self._tokens]) + return 'UnwrappedLine(depth={0}, tokens=[{1}])'.format( + self.depth, tokens_repr) + + ############################################################################ + # Properties # + ############################################################################ + + @property + def tokens(self): + """Access the tokens contained within this line. + + The caller must not modify the tokens list returned by this method. + + Returns: + List of tokens in this line. + """ + return self._tokens + + @property + def lineno(self): + """Return the line number of this unwrapped line. + + Returns: + The line number of the first token in this unwrapped line. + """ + return self.first.lineno + + @property + def is_comment(self): + return self.first.is_comment + + @property + def has_semicolon(self): + return any(tok.value == ';' for tok in self._tokens) + + +def _IsIdNumberStringToken(tok): + return tok.is_keyword or tok.is_name or tok.is_number or tok.is_string + + +def _IsUnaryOperator(tok): + return format_token.Subtype.UNARY_OPERATOR in tok.subtypes + + +def _HasPrecedence(tok): + """Whether a binary operation has precedence within its context.""" + node = tok.node + + # We let ancestor be the statement surrounding the operation that tok is the + # operator in. + ancestor = node.parent.parent + + while ancestor is not None: + # Search through the ancestor nodes in the parse tree for operators with + # lower precedence. + predecessor_type = pytree_utils.NodeName(ancestor) + if predecessor_type in ['arith_expr', 'term']: + # An ancestor "arith_expr" or "term" means we have found an operator + # with lower precedence than our tok. + return True + if predecessor_type != 'atom': + # We understand the context to look for precedence within as an + # arbitrary nesting of "arith_expr", "term", and "atom" nodes. If we + # leave this context we have not found a lower precedence operator. + return False + # Under normal usage we expect a complete parse tree to be available and + # we will return before we get an AttributeError from the root. + ancestor = ancestor.parent + + +def _PriorityIndicatingNoSpace(tok): + """Whether to remove spaces around an operator due to precedence.""" + if not tok.is_arithmetic_op or not tok.is_simple_expr: + # Limit space removal to highest priority arithmetic operators + return False + return _HasPrecedence(tok) + + +def _IsSubscriptColonAndValuePair(token1, token2): + return (token1.is_number or token1.is_name) and token2.is_subscript_colon + + +def _SpaceRequiredBetween(left, right, is_line_disabled): + """Return True if a space is required between the left and right token.""" + lval = left.value + rval = right.value + if (left.is_pseudo_paren and _IsIdNumberStringToken(right) and + left.previous_token and _IsIdNumberStringToken(left.previous_token)): + # Space between keyword... tokens and pseudo parens. + return True + if left.is_pseudo_paren or right.is_pseudo_paren: + # There should be a space after the ':' in a dictionary. + if left.OpensScope(): + return True + # The closing pseudo-paren shouldn't affect spacing. + return False + if left.is_continuation or right.is_continuation: + # The continuation node's value has all of the spaces it needs. + return False + if right.name in pytree_utils.NONSEMANTIC_TOKENS: + # No space before a non-semantic token. + return False + if _IsIdNumberStringToken(left) and _IsIdNumberStringToken(right): + # Spaces between keyword, string, number, and identifier tokens. + return True + if lval == ',' and rval == ':': + # We do want a space between a comma and colon. + return True + if style.Get('SPACE_INSIDE_BRACKETS'): + # Supersede the "no space before a colon or comma" check. + if lval in pytree_utils.OPENING_BRACKETS and rval == ':': + return True + if rval in pytree_utils.CLOSING_BRACKETS and lval == ':': + return True + if (style.Get('SPACES_AROUND_SUBSCRIPT_COLON') and + (_IsSubscriptColonAndValuePair(left, right) or + _IsSubscriptColonAndValuePair(right, left))): + # Supersede the "never want a space before a colon or comma" check. + return True + if rval in ':,': + # Otherwise, we never want a space before a colon or comma. + return False + if lval == ',' and rval in ']})': + # Add a space between ending ',' and closing bracket if requested. + return style.Get('SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET') + if lval == ',': + # We want a space after a comma. + return True + if lval == 'from' and rval == '.': + # Space before the '.' in an import statement. + return True + if lval == '.' and rval == 'import': + # Space after the '.' in an import statement. + return True + if (lval == '=' and rval == '.' and + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN not in left.subtypes): + # Space between equal and '.' as in "X = ...". + return True + if ((right.is_keyword or right.is_name) and + (left.is_keyword or left.is_name)): + # Don't merge two keywords/identifiers. + return True + if (format_token.Subtype.SUBSCRIPT_COLON in left.subtypes or + format_token.Subtype.SUBSCRIPT_COLON in right.subtypes): + # A subscript shouldn't have spaces separating its colons. + return False + if (format_token.Subtype.TYPED_NAME in left.subtypes or + format_token.Subtype.TYPED_NAME in right.subtypes): + # A typed argument should have a space after the colon. + return True + if left.is_string: + if (rval == '=' and format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST + in right.subtypes): + # If there is a type hint, then we don't want to add a space between the + # equal sign and the hint. + return False + if rval not in '[)]}.' and not right.is_binary_op: + # A string followed by something other than a subscript, closing bracket, + # dot, or a binary op should have a space after it. + return True + if rval in pytree_utils.CLOSING_BRACKETS: + # A string followed by closing brackets should have a space after it + # depending on SPACE_INSIDE_BRACKETS. A string followed by opening + # brackets, however, should not. + return style.Get('SPACE_INSIDE_BRACKETS') + if format_token.Subtype.SUBSCRIPT_BRACKET in right.subtypes: + # It's legal to do this in Python: 'hello'[a] + return False + if left.is_binary_op and lval != '**' and _IsUnaryOperator(right): + # Space between the binary operator and the unary operator. + return True + if left.is_keyword and _IsUnaryOperator(right): + # Handle things like "not -3 < x". + return True + if _IsUnaryOperator(left) and _IsUnaryOperator(right): + # No space between two unary operators. + return False + if left.is_binary_op or right.is_binary_op: + if lval == '**' or rval == '**': + # Space around the "power" operator. + return style.Get('SPACES_AROUND_POWER_OPERATOR') + # Enforce spaces around binary operators except the blocked ones. + block_list = style.Get('NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS') + if lval in block_list or rval in block_list: + return False + if style.Get('ARITHMETIC_PRECEDENCE_INDICATION'): + if _PriorityIndicatingNoSpace(left) or _PriorityIndicatingNoSpace(right): + return False + else: + return True + else: + return True + if (_IsUnaryOperator(left) and lval != 'not' and + (right.is_name or right.is_number or rval == '(')): + # The previous token was a unary op. No space is desired between it and + # the current token. + return False + if (format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN in left.subtypes and + format_token.Subtype.TYPED_NAME not in right.subtypes): + # A named argument or default parameter shouldn't have spaces around it. + return style.Get('SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN') + if (format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN in right.subtypes and + format_token.Subtype.TYPED_NAME not in left.subtypes): + # A named argument or default parameter shouldn't have spaces around it. + return style.Get('SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN') + if (format_token.Subtype.VARARGS_LIST in left.subtypes or + format_token.Subtype.VARARGS_LIST in right.subtypes): + return False + if (format_token.Subtype.VARARGS_STAR in left.subtypes or + format_token.Subtype.KWARGS_STAR_STAR in left.subtypes): + # Don't add a space after a vararg's star or a keyword's star-star. + return False + if lval == '@' and format_token.Subtype.DECORATOR in left.subtypes: + # Decorators shouldn't be separated from the 'at' sign. + return False + if left.is_keyword and rval == '.': + # Add space between keywords and dots. + return lval != 'None' and lval != 'print' + if lval == '.' and right.is_keyword: + # Add space between keywords and dots. + return rval != 'None' and rval != 'print' + if lval == '.' or rval == '.': + # Don't place spaces between dots. + return False + if ((lval == '(' and rval == ')') or (lval == '[' and rval == ']') or + (lval == '{' and rval == '}')): + # Empty objects shouldn't be separated by spaces. + return False + if not is_line_disabled and (left.OpensScope() or right.ClosesScope()): + if (style.GetOrDefault('SPACES_AROUND_DICT_DELIMITERS', False) and ( + (lval == '{' and _IsDictListTupleDelimiterTok(left, is_opening=True)) or + (rval == '}' and + _IsDictListTupleDelimiterTok(right, is_opening=False)))): + return True + if (style.GetOrDefault('SPACES_AROUND_LIST_DELIMITERS', False) and ( + (lval == '[' and _IsDictListTupleDelimiterTok(left, is_opening=True)) or + (rval == ']' and + _IsDictListTupleDelimiterTok(right, is_opening=False)))): + return True + if (style.GetOrDefault('SPACES_AROUND_TUPLE_DELIMITERS', False) and ( + (lval == '(' and _IsDictListTupleDelimiterTok(left, is_opening=True)) or + (rval == ')' and + _IsDictListTupleDelimiterTok(right, is_opening=False)))): + return True + if (lval in pytree_utils.OPENING_BRACKETS and + rval in pytree_utils.OPENING_BRACKETS): + # Nested objects' opening brackets shouldn't be separated, unless enabled + # by SPACE_INSIDE_BRACKETS. + return style.Get('SPACE_INSIDE_BRACKETS') + if (lval in pytree_utils.CLOSING_BRACKETS and + rval in pytree_utils.CLOSING_BRACKETS): + # Nested objects' closing brackets shouldn't be separated, unless enabled + # by SPACE_INSIDE_BRACKETS. + return style.Get('SPACE_INSIDE_BRACKETS') + if lval in pytree_utils.CLOSING_BRACKETS and rval in '([': + # A call, set, dictionary, or subscript that has a call or subscript after + # it shouldn't have a space between them. + return False + if lval in pytree_utils.OPENING_BRACKETS and _IsIdNumberStringToken(right): + # Don't separate the opening bracket from the first item, unless enabled + # by SPACE_INSIDE_BRACKETS. + return style.Get('SPACE_INSIDE_BRACKETS') + if left.is_name and rval in '([': + # Don't separate a call or array access from the name. + return False + if rval in pytree_utils.CLOSING_BRACKETS: + # Don't separate the closing bracket from the last item, unless enabled + # by SPACE_INSIDE_BRACKETS. + # FIXME(morbo): This might be too permissive. + return style.Get('SPACE_INSIDE_BRACKETS') + if lval == 'print' and rval == '(': + # Special support for the 'print' function. + return False + if lval in pytree_utils.OPENING_BRACKETS and _IsUnaryOperator(right): + # Don't separate a unary operator from the opening bracket, unless enabled + # by SPACE_INSIDE_BRACKETS. + return style.Get('SPACE_INSIDE_BRACKETS') + if (lval in pytree_utils.OPENING_BRACKETS and + (format_token.Subtype.VARARGS_STAR in right.subtypes or + format_token.Subtype.KWARGS_STAR_STAR in right.subtypes)): + # Don't separate a '*' or '**' from the opening bracket, unless enabled + # by SPACE_INSIDE_BRACKETS. + return style.Get('SPACE_INSIDE_BRACKETS') + if rval == ';': + # Avoid spaces before a semicolon. (Why is there a semicolon?!) + return False + if lval == '(' and rval == 'await': + # Special support for the 'await' keyword. Don't separate the 'await' + # keyword from an opening paren, unless enabled by SPACE_INSIDE_BRACKETS. + return style.Get('SPACE_INSIDE_BRACKETS') + return True + + +def _MustBreakBefore(prev_token, cur_token): + """Return True if a line break is required before the current token.""" + if prev_token.is_comment or (prev_token.previous_token and + prev_token.is_pseudo_paren and + prev_token.previous_token.is_comment): + # Must break if the previous token was a comment. + return True + if (cur_token.is_string and prev_token.is_string and + IsSurroundedByBrackets(cur_token)): + # We want consecutive strings to be on separate lines. This is a + # reasonable assumption, because otherwise they should have written them + # all on the same line, or with a '+'. + return True + return pytree_utils.GetNodeAnnotation( + cur_token.node, pytree_utils.Annotation.MUST_SPLIT, default=False) + + +def _CanBreakBefore(prev_token, cur_token): + """Return True if a line break may occur before the current token.""" + pval = prev_token.value + cval = cur_token.value + if py3compat.PY3: + if pval == 'yield' and cval == 'from': + # Don't break before a yield argument. + return False + if pval in {'async', 'await'} and cval in {'def', 'with', 'for'}: + # Don't break after sync keywords. + return False + if cur_token.split_penalty >= split_penalty.UNBREAKABLE: + return False + if pval == '@': + # Don't break right after the beginning of a decorator. + return False + if cval == ':': + # Don't break before the start of a block of code. + return False + if cval == ',': + # Don't break before a comma. + return False + if prev_token.is_name and cval == '(': + # Don't break in the middle of a function definition or call. + return False + if prev_token.is_name and cval == '[': + # Don't break in the middle of an array dereference. + return False + if cur_token.is_comment and prev_token.lineno == cur_token.lineno: + # Don't break a comment at the end of the line. + return False + if format_token.Subtype.UNARY_OPERATOR in prev_token.subtypes: + # Don't break after a unary token. + return False + if not style.Get('ALLOW_SPLIT_BEFORE_DEFAULT_OR_NAMED_ASSIGNS'): + if (format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN in cur_token.subtypes or + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN in prev_token.subtypes): + return False + return True + + +def IsSurroundedByBrackets(tok): + """Return True if the token is surrounded by brackets.""" + paren_count = 0 + brace_count = 0 + sq_bracket_count = 0 + previous_token = tok.previous_token + while previous_token: + if previous_token.value == ')': + paren_count -= 1 + elif previous_token.value == '}': + brace_count -= 1 + elif previous_token.value == ']': + sq_bracket_count -= 1 + + if previous_token.value == '(': + if paren_count == 0: + return previous_token + paren_count += 1 + elif previous_token.value == '{': + if brace_count == 0: + return previous_token + brace_count += 1 + elif previous_token.value == '[': + if sq_bracket_count == 0: + return previous_token + sq_bracket_count += 1 + + previous_token = previous_token.previous_token + return None + + +def _IsDictListTupleDelimiterTok(tok, is_opening): + assert tok + + if tok.matching_bracket is None: + return False + + if is_opening: + open_tok = tok + close_tok = tok.matching_bracket + else: + open_tok = tok.matching_bracket + close_tok = tok + + # There must be something in between the tokens + if open_tok.next_token == close_tok: + return False + + assert open_tok.next_token.node + assert open_tok.next_token.node.parent + + return open_tok.next_token.node.parent.type in [ + python_symbols.dictsetmaker, + python_symbols.listmaker, + python_symbols.testlist_gexp, + ] + + +_LOGICAL_OPERATORS = frozenset({'and', 'or'}) +_BITWISE_OPERATORS = frozenset({'&', '|', '^'}) +_ARITHMETIC_OPERATORS = frozenset({'+', '-', '*', '/', '%', '//', '@'}) + + +def _SplitPenalty(prev_token, cur_token): + """Return the penalty for breaking the line before the current token.""" + pval = prev_token.value + cval = cur_token.value + if pval == 'not': + return split_penalty.UNBREAKABLE + + if cur_token.node_split_penalty > 0: + return cur_token.node_split_penalty + + if style.Get('SPLIT_BEFORE_LOGICAL_OPERATOR'): + # Prefer to split before 'and' and 'or'. + if pval in _LOGICAL_OPERATORS: + return style.Get('SPLIT_PENALTY_LOGICAL_OPERATOR') + if cval in _LOGICAL_OPERATORS: + return 0 + else: + # Prefer to split after 'and' and 'or'. + if pval in _LOGICAL_OPERATORS: + return 0 + if cval in _LOGICAL_OPERATORS: + return style.Get('SPLIT_PENALTY_LOGICAL_OPERATOR') + + if style.Get('SPLIT_BEFORE_BITWISE_OPERATOR'): + # Prefer to split before '&', '|', and '^'. + if pval in _BITWISE_OPERATORS: + return style.Get('SPLIT_PENALTY_BITWISE_OPERATOR') + if cval in _BITWISE_OPERATORS: + return 0 + else: + # Prefer to split after '&', '|', and '^'. + if pval in _BITWISE_OPERATORS: + return 0 + if cval in _BITWISE_OPERATORS: + return style.Get('SPLIT_PENALTY_BITWISE_OPERATOR') + + if (format_token.Subtype.COMP_FOR in cur_token.subtypes or + format_token.Subtype.COMP_IF in cur_token.subtypes): + # We don't mind breaking before the 'for' or 'if' of a list comprehension. + return 0 + if format_token.Subtype.UNARY_OPERATOR in prev_token.subtypes: + # Try not to break after a unary operator. + return style.Get('SPLIT_PENALTY_AFTER_UNARY_OPERATOR') + if pval == ',': + # Breaking after a comma is fine, if need be. + return 0 + if pval == '**' or cval == '**': + return split_penalty.STRONGLY_CONNECTED + if (format_token.Subtype.VARARGS_STAR in prev_token.subtypes or + format_token.Subtype.KWARGS_STAR_STAR in prev_token.subtypes): + # Don't split after a varargs * or kwargs **. + return split_penalty.UNBREAKABLE + if prev_token.OpensScope() and cval != '(': + # Slightly prefer + return style.Get('SPLIT_PENALTY_AFTER_OPENING_BRACKET') + if cval == ':': + # Don't split before a colon. + return split_penalty.UNBREAKABLE + if cval == '=': + # Don't split before an assignment. + return split_penalty.UNBREAKABLE + if (format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN in prev_token.subtypes or + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN in cur_token.subtypes): + # Don't break before or after an default or named assignment. + return split_penalty.UNBREAKABLE + if cval == '==': + # We would rather not split before an equality operator. + return split_penalty.STRONGLY_CONNECTED + if cur_token.ClosesScope(): + # Give a slight penalty for splitting before the closing scope. + return 100 + return 0 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/verifier.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/verifier.py new file mode 100644 index 00000000..bcbe6fb6 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/verifier.py @@ -0,0 +1,93 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Verify that the generated code is valid code. + +This takes a line of code and "normalizes" it. I.e., it transforms the snippet +into something that has the potential to compile. + + VerifyCode(): the main function exported by this module. +""" + +import ast +import re +import sys +import textwrap + + +class InternalError(Exception): + """Internal error in verifying formatted code.""" + pass + + +def VerifyCode(code): + """Verify that the reformatted code is syntactically correct. + + Arguments: + code: (unicode) The reformatted code snippet. + + Raises: + SyntaxError if the code was reformatted incorrectly. + """ + try: + compile(textwrap.dedent(code).encode('UTF-8'), '', 'exec') + except SyntaxError: + try: + ast.parse(textwrap.dedent(code.lstrip('\n')).lstrip(), '', 'exec') + except SyntaxError: + try: + normalized_code = _NormalizeCode(code) + compile(normalized_code.encode('UTF-8'), '', 'exec') + except SyntaxError: + raise InternalError(sys.exc_info()[1]) + + +def _NormalizeCode(code): + """Make sure that the code snippet is compilable.""" + code = textwrap.dedent(code.lstrip('\n')).lstrip() + + # Split the code to lines and get rid of all leading full-comment lines as + # they can mess up the normalization attempt. + lines = code.split('\n') + i = 0 + for i, line in enumerate(lines): + line = line.strip() + if line and not line.startswith('#'): + break + code = '\n'.join(lines[i:]) + '\n' + + if re.match(r'(if|while|for|with|def|class|async|await)\b', code): + code += '\n pass' + elif re.match(r'(elif|else)\b', code): + try: + try_code = 'if True:\n pass\n' + code + '\n pass' + ast.parse( + textwrap.dedent(try_code.lstrip('\n')).lstrip(), '', 'exec') + code = try_code + except SyntaxError: + # The assumption here is that the code is on a single line. + code = 'if True: pass\n' + code + elif code.startswith('@'): + code += '\ndef _():\n pass' + elif re.match(r'try\b', code): + code += '\n pass\nexcept:\n pass' + elif re.match(r'(except|finally)\b', code): + code = 'try:\n pass\n' + code + '\n pass' + elif re.match(r'(return|yield)\b', code): + code = 'def _():\n ' + code + elif re.match(r'(continue|break)\b', code): + code = 'while True:\n ' + code + elif re.match(r'print\b', code): + code = 'from __future__ import print_function\n' + code + + return code + '\n' diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/yapf_api.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/yapf_api.py new file mode 100644 index 00000000..dde1df93 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapf/yapflib/yapf_api.py @@ -0,0 +1,319 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Entry points for YAPF. + +The main APIs that YAPF exposes to drive the reformatting. + + FormatFile(): reformat a file. + FormatCode(): reformat a string of code. + +These APIs have some common arguments: + + style_config: (string) Either a style name or a path to a file that contains + formatting style settings. If None is specified, use the default style + as set in style.DEFAULT_STYLE_FACTORY + lines: (list of tuples of integers) A list of tuples of lines, [start, end], + that we want to format. The lines are 1-based indexed. It can be used by + third-party code (e.g., IDEs) when reformatting a snippet of code rather + than a whole file. + print_diff: (bool) Instead of returning the reformatted source, return a + diff that turns the formatted source into reformatter source. + verify: (bool) True if reformatted code should be verified for syntax. +""" + +import difflib +import re +import sys + +from lib2to3.pgen2 import parse + +from yapf.yapflib import blank_line_calculator +from yapf.yapflib import comment_splicer +from yapf.yapflib import continuation_splicer +from yapf.yapflib import file_resources +from yapf.yapflib import identify_container +from yapf.yapflib import py3compat +from yapf.yapflib import pytree_unwrapper +from yapf.yapflib import pytree_utils +from yapf.yapflib import reformatter +from yapf.yapflib import split_penalty +from yapf.yapflib import style +from yapf.yapflib import subtype_assigner + + +def FormatFile(filename, + style_config=None, + lines=None, + print_diff=False, + verify=False, + in_place=False, + logger=None): + """Format a single Python file and return the formatted code. + + Arguments: + filename: (unicode) The file to reformat. + style_config: (string) Either a style name or a path to a file that contains + formatting style settings. If None is specified, use the default style + as set in style.DEFAULT_STYLE_FACTORY + lines: (list of tuples of integers) A list of tuples of lines, [start, end], + that we want to format. The lines are 1-based indexed. It can be used by + third-party code (e.g., IDEs) when reformatting a snippet of code rather + than a whole file. + print_diff: (bool) Instead of returning the reformatted source, return a + diff that turns the formatted source into reformatter source. + verify: (bool) True if reformatted code should be verified for syntax. + in_place: (bool) If True, write the reformatted code back to the file. + logger: (io streamer) A stream to output logging. + + Returns: + Tuple of (reformatted_code, encoding, changed). reformatted_code is None if + the file is successfully written to (having used in_place). reformatted_code + is a diff if print_diff is True. + + Raises: + IOError: raised if there was an error reading the file. + ValueError: raised if in_place and print_diff are both specified. + """ + _CheckPythonVersion() + + if in_place and print_diff: + raise ValueError('Cannot pass both in_place and print_diff.') + + original_source, newline, encoding = ReadFile(filename, logger) + reformatted_source, changed = FormatCode( + original_source, + style_config=style_config, + filename=filename, + lines=lines, + print_diff=print_diff, + verify=verify) + if reformatted_source.rstrip('\n'): + lines = reformatted_source.rstrip('\n').split('\n') + reformatted_source = newline.join(line for line in lines) + newline + if in_place: + if original_source and original_source != reformatted_source: + file_resources.WriteReformattedCode(filename, reformatted_source, + encoding, in_place) + return None, encoding, changed + + return reformatted_source, encoding, changed + + +def FormatCode(unformatted_source, + filename='', + style_config=None, + lines=None, + print_diff=False, + verify=False): + """Format a string of Python code. + + This provides an alternative entry point to YAPF. + + Arguments: + unformatted_source: (unicode) The code to format. + filename: (unicode) The name of the file being reformatted. + style_config: (string) Either a style name or a path to a file that contains + formatting style settings. If None is specified, use the default style + as set in style.DEFAULT_STYLE_FACTORY + lines: (list of tuples of integers) A list of tuples of lines, [start, end], + that we want to format. The lines are 1-based indexed. It can be used by + third-party code (e.g., IDEs) when reformatting a snippet of code rather + than a whole file. + print_diff: (bool) Instead of returning the reformatted source, return a + diff that turns the formatted source into reformatter source. + verify: (bool) True if reformatted code should be verified for syntax. + + Returns: + Tuple of (reformatted_source, changed). reformatted_source conforms to the + desired formatting style. changed is True if the source changed. + """ + _CheckPythonVersion() + style.SetGlobalStyle(style.CreateStyleFromConfig(style_config)) + if not unformatted_source.endswith('\n'): + unformatted_source += '\n' + + try: + tree = pytree_utils.ParseCodeToTree(unformatted_source) + except parse.ParseError as e: + e.msg = filename + ': ' + e.msg + raise + + # Run passes on the tree, modifying it in place. + comment_splicer.SpliceComments(tree) + continuation_splicer.SpliceContinuations(tree) + subtype_assigner.AssignSubtypes(tree) + identify_container.IdentifyContainers(tree) + split_penalty.ComputeSplitPenalties(tree) + blank_line_calculator.CalculateBlankLines(tree) + + uwlines = pytree_unwrapper.UnwrapPyTree(tree) + for uwl in uwlines: + uwl.CalculateFormattingInformation() + + lines = _LineRangesToSet(lines) + _MarkLinesToFormat(uwlines, lines) + reformatted_source = reformatter.Reformat( + _SplitSemicolons(uwlines), verify, lines) + + if unformatted_source == reformatted_source: + return '' if print_diff else reformatted_source, False + + code_diff = _GetUnifiedDiff( + unformatted_source, reformatted_source, filename=filename) + + if print_diff: + return code_diff, code_diff.strip() != '' # pylint: disable=g-explicit-bool-comparison + + return reformatted_source, True + + +def _CheckPythonVersion(): # pragma: no cover + errmsg = 'yapf is only supported for Python 2.7 or 3.4+' + if sys.version_info[0] == 2: + if sys.version_info[1] < 7: + raise RuntimeError(errmsg) + elif sys.version_info[0] == 3: + if sys.version_info[1] < 4: + raise RuntimeError(errmsg) + + +def ReadFile(filename, logger=None): + """Read the contents of the file. + + An optional logger can be specified to emit messages to your favorite logging + stream. If specified, then no exception is raised. This is external so that it + can be used by third-party applications. + + Arguments: + filename: (unicode) The name of the file. + logger: (function) A function or lambda that takes a string and emits it. + + Returns: + The contents of filename. + + Raises: + IOError: raised if there was an error reading the file. + """ + try: + encoding = file_resources.FileEncoding(filename) + + # Preserves line endings. + with py3compat.open_with_encoding( + filename, mode='r', encoding=encoding, newline='') as fd: + lines = fd.readlines() + + line_ending = file_resources.LineEnding(lines) + source = '\n'.join(line.rstrip('\r\n') for line in lines) + '\n' + return source, line_ending, encoding + except IOError as err: # pragma: no cover + if logger: + logger(err) + raise + except UnicodeDecodeError as err: # pragma: no cover + if logger: + logger('Could not parse %s! Consider excluding this file with --exclude.', + filename) + logger(err) + raise + + +def _SplitSemicolons(uwlines): + res = [] + for uwline in uwlines: + res.extend(uwline.Split()) + return res + + +DISABLE_PATTERN = r'^#.*\byapf:\s*disable\b' +ENABLE_PATTERN = r'^#.*\byapf:\s*enable\b' + + +def _LineRangesToSet(line_ranges): + """Return a set of lines in the range.""" + + if line_ranges is None: + return None + + line_set = set() + for low, high in sorted(line_ranges): + line_set.update(range(low, high + 1)) + + return line_set + + +def _MarkLinesToFormat(uwlines, lines): + """Skip sections of code that we shouldn't reformat.""" + if lines: + for uwline in uwlines: + uwline.disable = not lines.intersection( + range(uwline.lineno, uwline.last.lineno + 1)) + + # Now go through the lines and disable any lines explicitly marked as + # disabled. + index = 0 + while index < len(uwlines): + uwline = uwlines[index] + if uwline.is_comment: + if _DisableYAPF(uwline.first.value.strip()): + index += 1 + while index < len(uwlines): + uwline = uwlines[index] + if uwline.is_comment and _EnableYAPF(uwline.first.value.strip()): + if not re.search(DISABLE_PATTERN, + uwline.first.value.strip().split('\n')[-1].strip(), + re.IGNORECASE): + break + uwline.disable = True + index += 1 + elif re.search(DISABLE_PATTERN, uwline.last.value.strip(), re.IGNORECASE): + uwline.disable = True + index += 1 + + +def _DisableYAPF(line): + return (re.search(DISABLE_PATTERN, + line.split('\n')[0].strip(), re.IGNORECASE) or + re.search(DISABLE_PATTERN, + line.split('\n')[-1].strip(), re.IGNORECASE)) + + +def _EnableYAPF(line): + return (re.search(ENABLE_PATTERN, + line.split('\n')[0].strip(), re.IGNORECASE) or + re.search(ENABLE_PATTERN, + line.split('\n')[-1].strip(), re.IGNORECASE)) + + +def _GetUnifiedDiff(before, after, filename='code'): + """Get a unified diff of the changes. + + Arguments: + before: (unicode) The original source code. + after: (unicode) The reformatted source code. + filename: (unicode) The code's filename. + + Returns: + The unified diff text. + """ + before = before.splitlines() + after = after.splitlines() + return '\n'.join( + difflib.unified_diff( + before, + after, + filename, + filename, + '(original)', + '(reformatted)', + lineterm='')) + '\n' diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__init__.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__init__.py new file mode 100644 index 00000000..e7522b2c --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/__init__.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ef423db75b8f38767750b553da6ac5e072bc6c2 GIT binary patch literal 200 zcmYe~<>g`kf(3f>5<{367#@Q-$bb>ZaRB0C79f$r5X_*-=(m!g2qcUke&ylaj(WaQ`R2PbFb=jZ5qdb>Kt7bh1b7Ni#G>y@SE zmFeeXCP5V$>sjg-XO^Vu79=KTC#I(s>sKZgq?M!=1C5D~&&i#MW&i-RkT$CT literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/blank_line_calculator_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/blank_line_calculator_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b01e3b272fe2a6e36727f6deac40199e8c567bfc GIT binary patch literal 8671 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 literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/comment_splicer_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/comment_splicer_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..74378d4b41bd16fd38e0430ba7bc29424b4f7ae0 GIT binary patch literal 8800 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 literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/file_resources_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/file_resources_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ffc38e1afe3c70d900a0d2c38087da5c7bedc37 GIT binary patch literal 16564 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 a!TGY2o&Qzisrg6d=jLYS-#&k&VE!-E_W8#E literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/format_decision_state_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/format_decision_state_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a999565b9791eabeb757625a128e350ab3426bd2 GIT binary patch literal 3126 zcmcguTW=Fb6yBL#+v`g%B%zeva4D!*1-nuu)S?Ix<$@5!AlV49QnlLbjL9bJT{ANd zP2{u>@K9BK=^v=Ca%Se7Ip>=RW@btjJj41Q z!NwWO`U?x=j{}8U@X4P5nB`fFFd7q&m_PL>{O#E8I-WzY%>g;*<&2yIIq&6-oCmq! z6^vYn-EPq<66?0bTvmKxu_7;Sm!8{RnUz@ih2>TF46E!=vCrvnc4UDTZCSOM{mX4G zm8^DBQQZrAojM5JK>3V^k&M#Bmnu-a{x>YuYSxH8dty5@RC;?#aPIe26iX=Qq}q!) z2($gd<)l(_Jst-dHtY_d$0m<@wrT&;EKF!FOw2M})1A8o8FSqC}X1GO}8o)f?v?pYS{FDuRcFH2SPFy5(lt^`-Bo3$H9Rn=+_ zBI>9hFoiVfY_t!_6-|Oea#fSfLsB~=H)?0KtN4!!b6)2eXAt@VBT3Ib2!!M-343S= zLFBM^Y@CRxV7}|RAguvEI_tIUS zWq;a)#kA8Mp6D`Iz=c|W+7Dt~N}%3XrXjZ*#C@1NYu^ZB$+f#0B&}W?DLuEsm>Hm* znjyX7y}ndgTPag%3sBFk#wnQK2;LJf^V*R-?r0}W8TShPXUKh0=Q9D>5zNxL5LFCw zWPm4!zJz(+in_g+Z}gK;fvs!2^C(hV&D2bbj`$pU$~6Fsl$;V-BCcH_E}19u@CPKb z@A{`M*3{WRPlD-Y2@&B-$^={KJFv| zOz%4_<(=Weagr~ZBwrj)a#4YJsV#{m_=&R!n3>`O1WZS94&g(D^9Yz>;v7+Z~>u;fWas(B7A{x3E?sVo{3|Teeu+AI*#i{pdr5nI3=#Ls6GubmT$awEFVwa ztQEBD`$^E{zOPHZ-%VLRM!DkqNE=5jyF@qx@;iO%v@(Ngwsz2V zVMA|kp?SaATEDl_Y~NY++xPFTH(NETY5i+WJ8H}UhRsULG2Dg1wA;J+E6!(b7KD<@ ztNjaOY+qlF(-4^VCJ3+l!`&*M*;OL~uYzxlZ6fuT*MnL#Pn=h#4mYtIM2YX$=5)dL zSsMDjiF(iNCy~N1^eX1QivahoEY#6DbL}(P;1!QAT_#UF_wmYu4Wvc0by=QV0~PJy jWMhjv-g)gVXCZWR7MF>M=0J?Pv_i~FEA~RybzSlg59kn6 literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/format_token_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/format_token_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29cb6182f05ae1028e1952537c47bee8120d9d37 GIT binary patch literal 2515 zcmbtWOK;mo5MI71iHch%?jubR!A+W~aHPTkS`?^@xPDbgtOS-|6uc0$c5Tt-L*1p^ zns83Z?^z5N;}k)L{La>U}=1;j#{ zRV6ojCn;wPG(%cIaV9-G=s5YP(0K|?JOIH6Y=gKeZs`qiHL6h^-a0j?32%d15Q?2I zw*9?5M%R)!4dT9^21&dc1_$v=pVA;cz(6|+On3Qcpcv5Bpov`&RC%SO1Vxff+jI5a(t(U878yr`^z^&yZQ!AAVTs<=?_?&AT zDRl39AKpb?@`YeL-T1Tbhv!*sdZ}f1C&EJ_heb?&IGaQ(l>&OFQR#z3=)zBgrp(1FMV4Q*%#m` zF#Qo7#3g(9K18m4*Q^@+b6f>ei+_pY0g8tx#w(B05HFVBpa~rWq+yBU2qt;t2eIc> z%em!wH0gMrYxm?|{Y25((Fl|1l`QIJ}f?By!D%dlz$G mt|Md3bzJIw(dG6p!vgawUVQ@b(p6h^01-!<|9*bKR{jSg|6Ak$ literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/line_joiner_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/line_joiner_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21eaacf1b44c4b41d672353d1442db30caac848b GIT binary patch literal 3012 zcmbuBTW=dh6vy{wdwt2JDFv#6Iw}&ysMtsqD2>{xk(*X6X^3#D!alIt?3~1#tar`K zI2X%2HLrXHlsx8p@G16{C%yttoUs-Lfz5R+;9xc&CqOHj-^wbh2@-+OUt=1-!3=>U3;nVJTDw* zya0tQ`@QKDp~UTNLpWd@mX9=SZ8WuNv3F+;q>^kS7Hr?^Y}CRa0(UD$D{6nC1KLVe zPs$@-@iiyaeh65Yr7o_*5!@Dp9S}bC7)>U=Ji|w>q5%y>XpR9UNjcEo>yE`uZXIY& zj^}tDb99>9m=}1FmoT?^nO86`@+m%zd5O>PS-t=2>9M)fbx3uU=UwFu;UfY3a zryd6DCygG~9@S-_;H!@3Z+n{{>x7huN^CX!6)EFdXFn-PP;Wbp(3A2G$uiJrM(_4n z47Jl%K8YJ7qLITVCBm>kMEd%X{;SzXF3LQ#`sR_|H;xPnC*))F{%Ewo-)5@iDKx+~ z1C+qtM!P7e1Dqz7%oD)UpyAAu4E8$UE8w+KiD6n4n;Dpe^p!C`=CHula4;${6*E7Z zBW4nS1siM^tGp;3k_D=E(vN0viHgMDqC04rO_w^CR?>j$1AnrF42DM*88^DcgtH^}AR1kIHgfC-j$GWKCz{h4{ zE7()?lao9Lj&UufsKOAmdxnGvRv4>^&G0 z{;yrH2jOvsU>w5w3520`YIY9D3o%V1XUNbNGOqdVspF%uGE`k3QEl~V7pk7v`Fgs4 zoUGfQqf^DPCr}gAf+r#tTMeho(%VXbl#Vq!6>~0h&67E#eD=QhiQKd(Bc9$y- yFHza4Z~wHo`eF@xq(cjuJF#f=N$w@~;|#!4+WI9;X&JU|8x_4`RLr?~TmJ{HEDE{+ literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/main_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/main_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40fa18d00a1b448ef01b096ff5ad769b7dfb01bf GIT binary patch literal 5548 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 literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/pytree_visitor_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/pytree_visitor_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1a4dcc19b713fd8ef176a0a4775551e3740f02d GIT binary patch literal 3657 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 M(6YLJ!=0`F6ZrMe7ytkO literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_buganizer_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_buganizer_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..45c217d0dc91563fb2e09425134567f6c22c8e5b GIT binary patch literal 80291 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 Q7N+xuewLxX=Zo3@0#wU0xBvhE literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_pep8_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_pep8_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..719567478780bb673a04c7fd7ab452c0ebca8d4a GIT binary patch literal 29269 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 z z&!u}zmtKs7lqgnf2Dyr-NMY__!|IVmr&^#idK3^~lZXO1*WxrIQa7R$5tr~*tWpFD zLC#f?tHa$HJ@gSYa`X9L^zX{qa9~cC=M8lR* z99qU#P#@`Pi9e14^P&U~Lp*Dq-F z+NT7vU}`t9vFWVf=#9apN!Uzk=mW?EXELjF;>WMFfs~`u#Y!i49}o+%H0$BR%{+ zobzeKbMDOsv;Kvwcn>PpA{(GyKCl9|z#RuC46$XP299&ofu&LgeHXg5&2!fmLdzkw zL081Vr3?-aB1+~+v7#H!T67Dw*U80n}I#y zWcyB>X?-QNA4+2Kxc z&-sA4caFg$;-y}!k`7|#)h3Qv!t5_yUszZG@~4A@E)4C`G|nn~g|!0c4+3lHf@ut| zUGLq`s$p+A?6rqm2?Rx%`Ux=G|N4f8B8L&6OrN+M){)%EFpqp4H0&dV{4w{~5L+aU zEfJQ)@0v-|5S;O%z_4c+WGo8Nq#Ab7T<70NeY-n`LoYWBucTF;x!TEKBMhs9rggHK z<{dD?^SGwb`P=T75lv%u71?7F&wHni1jSm#c}gx&auG=<)3o4FVIJZr_pZ@+WWl3! z1Rdk9q}PA4cuQQOqI7aVT%qI|B{@oFD4C_?LrU_L%u!OHWS)`*O0H9~NXbW(5Ly-= zQ-c4Skq~z%A-78W5ha99L&+Gu5^$g`KZlBCl(eGY3`6E*W+F2_j*};u@yu}MeCAB% zEPmO{NajjrEOQ#a)yzed8N+WhGntu?bclO&Hb>KDCgmwf&$*DNWJ(}k8JGX_f)X5# zmwfO}V3DDyj0T6|J^%H`$n2!Rrb^}~rS(;^NwO6|3u`A$4TT0H$3`RSWPaqy?GtL( cA-<-SOcFn3Jc*w&o*GY{{j&u9mNLoz16j%tJpcdz literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_style_config_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/reformatter_style_config_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..494cb563b41b408fd62af2d23d2238c9fdad1ad0 GIT binary patch literal 6120 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 literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/split_penalty_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/split_penalty_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb021cb94180feb6a77025b8fcbca6199ad5b8a5 GIT binary patch literal 4809 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 T;rG*!q6}j{$}o literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/style_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/style_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1855d191f9081653ec1cfc722f62d4078e27335a GIT binary patch literal 12797 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 G^8W&lkFDtd literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/subtype_assigner_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/subtype_assigner_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4635c13677aca616e9b6945ae055cbf8a0440b4 GIT binary patch literal 6369 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 F{TFyT!qor( literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/unwrapped_line_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/unwrapped_line_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c1f371802880f117da4797813145e4fca5f16842 GIT binary patch literal 3956 zcmbtX-E-T<5x+ZtAow9!Qk69BC(|^E*v4dPXQs95dh}tdlZnE5WTn$!+G1edQKAHb z%mH*Fj`U>z1MMHsp=SExe+jRB@^jz((Db(l3M3^(NvD{(#opf6-tG^(i(p})%U&T%G7C9?!&U?~$urWAJ%lAW^+3xoS58i<~|3+h@-(GG02JN)fkK#lR+ex<{ zHSUM~b`Zu7z?|<=FQu#gr@@ihHrU!DsO?}-lZiAwI;IzhI3Vf5+(Bt2h-0ObM_&ws zFfB+mNDflRfHQt+rFN{sPHLkcr`GVxaB4qo+_Q91y`SQU*aczyEnek|eDwa@c{#2w zU2M+3q<9XrzoK&)XaJloEdb6kfGYrGb`H2AcmQhxxS}keS2`@`eFyzY);FLlwsZ-n zyyk0~qLr=?$qiSp>hF^vH)m?^Jl@!y8dbkV!#9ci039YeDOCMZyg){&&Gqf#_k!*zey)EkA54Q z83Vnd4{%hf;c3*?YA5y51qPm~0$s*bKEv%1C=E%)4dixqv zWUJ=vKsx3iYN3;`F|x`T;?oHqi^NLo!-5pg#TiFjI+q|;O(bj#7|lc~ekoFE3XaAq zuX){EIkk6zj7w?|a;}M088U9rX3Iq8fui4l?AIiJ6J&JnIx8RvMbZR-s{@6J0md6% zWn((|iuj>|P6l}6$vPcx0RBU8FNOXw3FvFTplo`>_;9-Q9n6_Tgfd*Y!bk6Yw+mb{ zB89Il+AYgG^S&J0N#W3u;%vs7Mpl&8M8?MM1%H+xs+4p;WISh%f`aWfvY(&>c1qyuneIg$aX%LyJWjM+;nz9O^&O`-QxQ^?h zIY!=weC{CwtfR%W^m0XnI>S!qahT=Kq#Nyj9Az~cvh5z?(VXuoo>0YVaQFhuG^QkC zOcf7D#UrG+$tXSDWTzG?p2CTB=$I&z@x=-6LS9PF6Vv%B8>?)y%AQ$eqkf_|1r(py z(^V#Y6)R$8*9#pj9-315<8P2%g)+sQplNHnE%W zF5_jpEEZ91RQb~6J-R)I({J>xsX`_jw(7QSVpIJgkzWz{4Uwy`cpC%jXfff;6`J~O z;?E!A^LRxCD&fQ+1eu275fI4fL;{mn$rLnk+kCs4(qCPqWmAdy$?-s?m5hHDghMr> zl=(J(f$4i_MjysC_2+O)t|pxfZs|t!cZKSkQ3Ql8R%>oLg*S4S$yrp=nEHC<&*BvD zPH=@2q|L0(HmcOKBkPu?yK0IX`W}&~@r<67$v#Jm>DrEPz8n7)T%Tts1 z#uo9#L#S5!6CFYhVB8VnKc+gNkkkvhk?+^vNQ=HN`)%LXA7PH?4x?^D;PQ$n?QbXj zJH`#(!lc(2?5pUu$%kIm{PGdOpz)t3Q<+HYmGbI8`+i)CAX@=SYzkkV`}xM>Z4w#8 w7&m2w69F%^NxPZb|Z5@MrM{%>G8@W<%>2 zF!XN#oQw#koHcYry<{WiWiSf73`e1t(I^sh67ztEFUbo!O1!qiQ{H(=K~KGYi}(1p z*E^g&BiZiR-5*We)TS1?UrE(BLK{7}gqO*%q$t*nflOhPF!TceLnd@dEyyuF+vVgZ zLdnm>QqtwfYxP5nOyV$q(gJcrJ9lC}x%aU_OUW>%nZ{Zm*smE5U0eN+Z=<_(2~b7SotAnlhE3Tfxc0gUi>@ z_R9|F*R2PW4KXb!NDQY(MD5v#vpG@sc(9CY?B{ztT*ih?0t+iPu_=$v!(Z95v+SC1 z64{Og3N5pN4S9SXFSqQL?N$uQwObeQE089+NNx8OrNoCYIs5c0*&1XHpev(XZ-8^y?N@aJS@Qkg>}Ee7;2DhmN?wOlMgL(V16Oed^+w z5-0;;$Ax$-i(H5&UFQI{2nEl$RJ5h!IE#f+QfZgKyG`AStfMe-T<;jdSj%=?x0Q4$ zdW62XWO}4gajcdulrzz~sBEMbj!DQCC8qLNWIgo;T%ztE+(md3;U2;c!Yu%ofQxN0 z73wx>tl}=JPn;l+{F{CiCumpi z!Op8_ZmP#0D-3>#++8=!lub5#4~iic3V0n+b{_ry2%;S=V;fyiOEHQtV;EN(uS$rM z5c-RNl6Ln)qMtqi8}?sd_;Lz{j-F(ZdIzpwG2=#QhRvYy9oH78*J@f6XnwkPJRn^jR#4xA&0Vm<0z({pbRV!c%(sLr3`)B z2e;nGCFE?FbzL$Zb6JkZuIpVoHBh?hZQOAm0rSQequW{A*Xix6(f?54OE=v0j{69w mpFxh!8}T`&h8_TfEQR3t9)z@eCtQ(w6aVSm4+Bs2fByq$LsFIi literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/yapf_test.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/yapf_test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9887975b2e59c10235100c429045d1c362124aa3 GIT binary patch literal 56085 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�PaM;lbw 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 literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/yapf_test_helper.cpython-39.pyc b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/__pycache__/yapf_test_helper.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f8aaddf54205c5c60faed28f4d3d47aa709bbe60 GIT binary patch literal 2403 zcmZuyPj4GV6yLx0dSg3j(gH$Ih9VG_z&>!os;Z_*Q$?g9BI$vV&}y?Ywl`VtZf9oO z+S;6&Yrg_=j@iP_y#;d+vuW<|T8eP-a2i&G@jn@EoXh-8V;4bZ&#uI~eSohLkU2dPPzqaWH+hiN; z)}={rG3(gqZO!i;7kQouMWz`m5>7^$Ac{*RHJXL_sQ)|sopIPRt2?Jjn4Skoobn(F zlc-2Sl?m8bkFx2Mrz((n5=R`DZbwi9XG&dM(wXl1N>!!ZJf&ce*0+e1dI{caA@^30JPxUfmi+tU1^o(xh;M{ zZ;!1DTNw-R_mz3!l;*;^GIot0`WLRUOZT-|I_HjfRN4!NIi>rKab=pu^Lu*k-k3LV zueAPG!sQJK?1qGT-qaH8g{vB8&011@Bj&Ld^V!-PSD!Ez9&0aJCEOY3%z(e|9M13T zWK0uc8Uj6H2}3j)&RdUPOP?%xo2h!hWkG@SAvsQe(P zQvl$05TM3-M|=b-wI!}~cX6!^9f4P3FnN}q??pISJuU#uk~&uA05CR6VEu)qtc6`# z$T#II+$Cx(fTw!R13uQsU#u-rd(o*;X$q>kXX~Yk}#3@fHN>Ku}IL{3Bj%JEA2Fe7zpB%g=CC-I-l^hhiT3gAr3LY?&k>ZD>^ zh(38H`KU;A)@S^*7>_}-zU+5g6(W`ORSzHrNH%)=KTGTNL2l2a9Tkc(hcW;+4X3?3 zq6sdi>)M3KPXjzm`j1wq+2`7(#0QPIXl3FB0Svjcfm$SGrVJE%bBbi zwQ&TdeA<4di&MQ%@4l6?2LuQe)VlG0ie%6gujh*Q@gr~Lx5`29(Pr^d(~a5yZp2g7 z)rQ(mS*__l2#_en==u=kZ=2;n*!!3QEb$ra_RPKBX4MP=mPJ7z-i0Oc33SwhJg6|M z(6%n**g-zhX3$R1M%Sj)zo^}%O`)x*b8l^Z53Ar#2>A$OUTeK}dCZamGeYIvuXD(Q VF3cn@ITj`>&%$JNquHAu{0(S_lX?IE literal 0 HcmV?d00001 diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/blank_line_calculator_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/blank_line_calculator_test.py new file mode 100644 index 00000000..1ec0a5e5 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/blank_line_calculator_test.py @@ -0,0 +1,422 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.blank_line_calculator.""" + +import textwrap +import unittest + +from yapf.yapflib import reformatter +from yapf.yapflib import style +from yapf.yapflib import yapf_api + +from yapftests import yapf_test_helper + + +class BasicBlankLineCalculatorTest(yapf_test_helper.YAPFTest): + + @classmethod + def setUpClass(cls): + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testDecorators(self): + unformatted_code = textwrap.dedent("""\ + @bork() + + def foo(): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + @bork() + def foo(): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testComplexDecorators(self): + unformatted_code = textwrap.dedent("""\ + import sys + @bork() + + def foo(): + pass + @fork() + + class moo(object): + @bar() + @baz() + + def method(self): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + import sys + + + @bork() + def foo(): + pass + + + @fork() + class moo(object): + + @bar() + @baz() + def method(self): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testCodeAfterFunctionsAndClasses(self): + unformatted_code = textwrap.dedent("""\ + def foo(): + pass + top_level_code = True + class moo(object): + def method_1(self): + pass + ivar_a = 42 + ivar_b = 13 + def method_2(self): + pass + try: + raise Error + except Error as error: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): + pass + + + top_level_code = True + + + class moo(object): + + def method_1(self): + pass + + ivar_a = 42 + ivar_b = 13 + + def method_2(self): + pass + + + try: + raise Error + except Error as error: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testCommentSpacing(self): + unformatted_code = textwrap.dedent("""\ + # This is the first comment + # And it's multiline + + # This is the second comment + + def foo(): + pass + + # multiline before a + # class definition + + # This is the second comment + + class qux(object): + pass + + + # An attached comment. + class bar(object): + '''class docstring''' + # Comment attached to + # function + def foo(self): + '''Another docstring.''' + # Another multiline + # comment + pass + """) + expected_formatted_code = textwrap.dedent("""\ + # This is the first comment + # And it's multiline + + # This is the second comment + + + def foo(): + pass + + + # multiline before a + # class definition + + # This is the second comment + + + class qux(object): + pass + + + # An attached comment. + class bar(object): + '''class docstring''' + + # Comment attached to + # function + def foo(self): + '''Another docstring.''' + # Another multiline + # comment + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testCommentBeforeMethod(self): + code = textwrap.dedent("""\ + class foo(object): + + # pylint: disable=invalid-name + def f(self): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testCommentsBeforeClassDefs(self): + code = textwrap.dedent('''\ + """Test.""" + + # Comment + + + class Foo(object): + pass + ''') + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testCommentsBeforeDecorator(self): + code = textwrap.dedent("""\ + # The @foo operator adds bork to a(). + @foo() + def a(): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + code = textwrap.dedent("""\ + # Hello world + + + @foo() + def a(): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testCommentsAfterDecorator(self): + code = textwrap.dedent("""\ + class _(): + + def _(): + pass + + @pytest.mark.xfail(reason="#709 and #710") + # also + #@pytest.mark.xfail(setuptools.tests.is_ascii, + # reason="https://github.com/pypa/setuptools/issues/706") + def test_unicode_filename_in_sdist(self, sdist_unicode, tmpdir, monkeypatch): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testInnerClasses(self): + unformatted_code = textwrap.dedent("""\ + class DeployAPIClient(object): + class Error(Exception): pass + + class TaskValidationError(Error): pass + + class DeployAPIHTTPError(Error): pass + """) + expected_formatted_code = textwrap.dedent("""\ + class DeployAPIClient(object): + + class Error(Exception): + pass + + class TaskValidationError(Error): + pass + + class DeployAPIHTTPError(Error): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testLinesOnRangeBoundary(self): + unformatted_code = textwrap.dedent(u"""\ + def A(): + pass + + def B(): # 4 + pass # 5 + + def C(): + pass + def D(): # 9 + pass # 10 + def E(): + pass + """) + expected_formatted_code = textwrap.dedent(u"""\ + def A(): + pass + + + def B(): # 4 + pass # 5 + + + def C(): + pass + + + def D(): # 9 + pass # 10 + + + def E(): + pass + """) + code, changed = yapf_api.FormatCode( + unformatted_code, lines=[(4, 5), (9, 10)]) + self.assertCodeEqual(expected_formatted_code, code) + self.assertTrue(changed) + + def testLinesRangeBoundaryNotOutside(self): + unformatted_code = textwrap.dedent(u"""\ + def A(): + pass + + + + def B(): # 6 + pass # 7 + + + + def C(): + pass + """) + expected_formatted_code = textwrap.dedent(u"""\ + def A(): + pass + + + + def B(): # 6 + pass # 7 + + + + def C(): + pass + """) + code, changed = yapf_api.FormatCode(unformatted_code, lines=[(6, 7)]) + self.assertCodeEqual(expected_formatted_code, code) + self.assertFalse(changed) + + def testLinesRangeRemove(self): + unformatted_code = textwrap.dedent(u"""\ + def A(): + pass + + + + def B(): # 6 + pass # 7 + + + + + def C(): + pass + """) + expected_formatted_code = textwrap.dedent(u"""\ + def A(): + pass + + + def B(): # 6 + pass # 7 + + + def C(): + pass + """) + code, changed = yapf_api.FormatCode(unformatted_code, lines=[(5, 9)]) + self.assertCodeEqual(expected_formatted_code, code) + self.assertTrue(changed) + + def testLinesRangeRemoveSome(self): + unformatted_code = textwrap.dedent(u"""\ + def A(): + pass + + + + + def B(): # 7 + pass # 8 + + + + + def C(): + pass + """) + expected_formatted_code = textwrap.dedent(u"""\ + def A(): + pass + + + + def B(): # 7 + pass # 8 + + + + def C(): + pass + """) + code, changed = yapf_api.FormatCode(unformatted_code, lines=[(6, 9)]) + self.assertCodeEqual(expected_formatted_code, code) + self.assertTrue(changed) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/comment_splicer_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/comment_splicer_test.py new file mode 100644 index 00000000..aacc8882 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/comment_splicer_test.py @@ -0,0 +1,334 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.comment_splicer.""" + +import textwrap +import unittest + +from yapf.yapflib import comment_splicer +from yapf.yapflib import py3compat +from yapf.yapflib import pytree_utils + + +class CommentSplicerTest(unittest.TestCase): + + def _AssertNodeType(self, expected_type, node): + self.assertEqual(expected_type, pytree_utils.NodeName(node)) + + def _AssertNodeIsComment(self, node, text_in_comment=None): + if pytree_utils.NodeName(node) == 'simple_stmt': + self._AssertNodeType('COMMENT', node.children[0]) + node_value = node.children[0].value + else: + self._AssertNodeType('COMMENT', node) + node_value = node.value + if text_in_comment is not None: + self.assertIn(text_in_comment, node_value) + + def _FindNthChildNamed(self, node, name, n=1): + for i, child in enumerate( + py3compat.ifilter(lambda c: pytree_utils.NodeName(c) == name, + node.pre_order())): + if i == n - 1: + return child + raise RuntimeError('No Nth child for n={0}'.format(n)) + + def testSimpleInline(self): + code = 'foo = 1 # and a comment\n' + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + expr = tree.children[0].children[0] + # Check that the expected node is still expr_stmt, but now it has 4 children + # (before comment splicing it had 3), the last child being the comment. + self._AssertNodeType('expr_stmt', expr) + self.assertEqual(4, len(expr.children)) + comment_node = expr.children[3] + self._AssertNodeIsComment(comment_node, '# and a comment') + + def testSimpleSeparateLine(self): + code = textwrap.dedent(r''' + foo = 1 + # first comment + bar = 2 + ''') + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + # The comment should've been added to the root's children (now 4, including + # the ENDMARKER in the end. + self.assertEqual(4, len(tree.children)) + comment_node = tree.children[1] + self._AssertNodeIsComment(comment_node) + + def testTwoLineComment(self): + code = textwrap.dedent(r''' + foo = 1 + # first comment + # second comment + bar = 2 + ''') + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + # This is similar to the single-line standalone comment. + self.assertEqual(4, len(tree.children)) + self._AssertNodeIsComment(tree.children[1]) + + def testCommentIsFirstChildInCompound(self): + code = textwrap.dedent(r''' + if x: + # a comment + foo = 1 + ''') + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + # Look into the suite node under the 'if'. We don't care about the NEWLINE + # leaf but the new COMMENT must be a child of the suite and before the + # actual code leaf. + if_suite = tree.children[0].children[3] + self._AssertNodeType('NEWLINE', if_suite.children[0]) + self._AssertNodeIsComment(if_suite.children[1]) + + def testCommentIsLastChildInCompound(self): + code = textwrap.dedent(r''' + if x: + foo = 1 + # a comment + ''') + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + # Look into the suite node under the 'if'. We don't care about the DEDENT + # leaf but the new COMMENT must be a child of the suite and after the + # actual code leaf. + if_suite = tree.children[0].children[3] + self._AssertNodeType('DEDENT', if_suite.children[-1]) + self._AssertNodeIsComment(if_suite.children[-2]) + + def testInlineAfterSeparateLine(self): + code = textwrap.dedent(r''' + bar = 1 + # line comment + foo = 1 # inline comment + ''') + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + # The separate line comment should become a child of the root, while + # the inline comment remains within its simple_node. + sep_comment_node = tree.children[1] + self._AssertNodeIsComment(sep_comment_node, '# line comment') + + expr = tree.children[2].children[0] + inline_comment_node = expr.children[-1] + self._AssertNodeIsComment(inline_comment_node, '# inline comment') + + def testSeparateLineAfterInline(self): + code = textwrap.dedent(r''' + bar = 1 + foo = 1 # inline comment + # line comment + ''') + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + # The separate line comment should become a child of the root, while + # the inline comment remains within its simple_node. + sep_comment_node = tree.children[-2] + self._AssertNodeIsComment(sep_comment_node, '# line comment') + + expr = tree.children[1].children[0] + inline_comment_node = expr.children[-1] + self._AssertNodeIsComment(inline_comment_node, '# inline comment') + + def testCommentBeforeDedent(self): + code = textwrap.dedent(r''' + if bar: + z = 1 + # a comment + j = 2 + ''') + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + # The comment should go under the tree root, not under the 'if'. + self._AssertNodeIsComment(tree.children[1]) + if_suite = tree.children[0].children[3] + self._AssertNodeType('DEDENT', if_suite.children[-1]) + + def testCommentBeforeDedentTwoLevel(self): + code = textwrap.dedent(r''' + if foo: + if bar: + z = 1 + # a comment + y = 1 + ''') + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + if_suite = tree.children[0].children[3] + # The comment is in the first if_suite, not the nested if under it. It's + # right before the DEDENT + self._AssertNodeIsComment(if_suite.children[-2]) + self._AssertNodeType('DEDENT', if_suite.children[-1]) + + def testCommentBeforeDedentTwoLevelImproperlyIndented(self): + code = textwrap.dedent(r''' + if foo: + if bar: + z = 1 + # comment 2 + y = 1 + ''') + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + # The comment here is indented by 3 spaces, which is unlike any of the + # surrounding statement indentation levels. The splicer attaches it to the + # "closest" parent with smaller indentation. + if_suite = tree.children[0].children[3] + # The comment is in the first if_suite, not the nested if under it. It's + # right before the DEDENT + self._AssertNodeIsComment(if_suite.children[-2]) + self._AssertNodeType('DEDENT', if_suite.children[-1]) + + def testCommentBeforeDedentThreeLevel(self): + code = textwrap.dedent(r''' + if foo: + if bar: + z = 1 + # comment 2 + # comment 1 + # comment 0 + j = 2 + ''') + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + # comment 0 should go under the tree root + self._AssertNodeIsComment(tree.children[1], '# comment 0') + + # comment 1 is in the first if_suite, right before the DEDENT + if_suite_1 = self._FindNthChildNamed(tree, 'suite', n=1) + self._AssertNodeIsComment(if_suite_1.children[-2], '# comment 1') + self._AssertNodeType('DEDENT', if_suite_1.children[-1]) + + # comment 2 is in if_suite nested under the first if suite, + # right before the DEDENT + if_suite_2 = self._FindNthChildNamed(tree, 'suite', n=2) + self._AssertNodeIsComment(if_suite_2.children[-2], '# comment 2') + self._AssertNodeType('DEDENT', if_suite_2.children[-1]) + + def testCommentsInClass(self): + code = textwrap.dedent(r''' + class Foo: + """docstring abc...""" + # top-level comment + def foo(): pass + # another comment + ''') + + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + class_suite = tree.children[0].children[3] + another_comment = class_suite.children[-2] + self._AssertNodeIsComment(another_comment, '# another') + + # It's OK for the comment to be a child of funcdef, as long as it's + # the first child and thus comes before the 'def'. + funcdef = class_suite.children[3] + toplevel_comment = funcdef.children[0] + self._AssertNodeIsComment(toplevel_comment, '# top-level') + + def testMultipleBlockComments(self): + code = textwrap.dedent(r''' + # Block comment number 1 + + # Block comment number 2 + def f(): + pass + ''') + + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + funcdef = tree.children[0] + block_comment_1 = funcdef.children[0] + self._AssertNodeIsComment(block_comment_1, '# Block comment number 1') + + block_comment_2 = funcdef.children[1] + self._AssertNodeIsComment(block_comment_2, '# Block comment number 2') + + def testCommentsOnDedents(self): + code = textwrap.dedent(r''' + class Foo(object): + # A comment for qux. + def qux(self): + pass + + # Interim comment. + + def mux(self): + pass + ''') + + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + classdef = tree.children[0] + class_suite = classdef.children[6] + qux_comment = class_suite.children[1] + self._AssertNodeIsComment(qux_comment, '# A comment for qux.') + + interim_comment = class_suite.children[4] + self._AssertNodeIsComment(interim_comment, '# Interim comment.') + + def testExprComments(self): + code = textwrap.dedent(r''' + foo( # Request fractions of an hour. + 948.0/3600, 20) + ''') + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + trailer = self._FindNthChildNamed(tree, 'trailer', 1) + comment = trailer.children[1] + self._AssertNodeIsComment(comment, '# Request fractions of an hour.') + + def testMultipleCommentsInOneExpr(self): + code = textwrap.dedent(r''' + foo( # com 1 + 948.0/3600, # com 2 + 20 + 12 # com 3 + ) + ''') + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + + trailer = self._FindNthChildNamed(tree, 'trailer', 1) + self._AssertNodeIsComment(trailer.children[1], '# com 1') + + arglist = self._FindNthChildNamed(tree, 'arglist', 1) + self._AssertNodeIsComment(arglist.children[2], '# com 2') + + arith_expr = self._FindNthChildNamed(tree, 'arith_expr', 1) + self._AssertNodeIsComment(arith_expr.children[-1], '# com 3') + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/file_resources_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/file_resources_test.py new file mode 100644 index 00000000..a4b12305 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/file_resources_test.py @@ -0,0 +1,493 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.file_resources.""" + +import contextlib +import os +import shutil +import tempfile +import unittest + +from yapf.yapflib import errors +from yapf.yapflib import file_resources +from yapf.yapflib import py3compat + +from yapftests import utils + + +@contextlib.contextmanager +def _restore_working_dir(): + curdir = os.getcwd() + try: + yield + finally: + os.chdir(curdir) + + +@contextlib.contextmanager +def _exists_mocked_in_module(module, mock_implementation): + unmocked_exists = getattr(module, 'exists') + setattr(module, 'exists', mock_implementation) + try: + yield + finally: + setattr(module, 'exists', unmocked_exists) + + +class GetExcludePatternsForDir(unittest.TestCase): + + def setUp(self): # pylint: disable=g-missing-super-call + self.test_tmpdir = tempfile.mkdtemp() + + def tearDown(self): # pylint: disable=g-missing-super-call + shutil.rmtree(self.test_tmpdir) + + def _make_test_dir(self, name): + fullpath = os.path.normpath(os.path.join(self.test_tmpdir, name)) + os.makedirs(fullpath) + return fullpath + + def test_get_exclude_file_patterns(self): + local_ignore_file = os.path.join(self.test_tmpdir, '.yapfignore') + ignore_patterns = ['temp/**/*.py', 'temp2/*.py'] + with open(local_ignore_file, 'w') as f: + f.writelines('\n'.join(ignore_patterns)) + + self.assertEqual( + sorted(file_resources.GetExcludePatternsForDir(self.test_tmpdir)), + sorted(ignore_patterns)) + + +class GetDefaultStyleForDirTest(unittest.TestCase): + + def setUp(self): # pylint: disable=g-missing-super-call + self.test_tmpdir = tempfile.mkdtemp() + + def tearDown(self): # pylint: disable=g-missing-super-call + shutil.rmtree(self.test_tmpdir) + + def test_no_local_style(self): + test_file = os.path.join(self.test_tmpdir, 'file.py') + style_name = file_resources.GetDefaultStyleForDir(test_file) + self.assertEqual(style_name, 'pep8') + + def test_no_local_style_custom_default(self): + test_file = os.path.join(self.test_tmpdir, 'file.py') + style_name = file_resources.GetDefaultStyleForDir( + test_file, default_style='custom-default') + self.assertEqual(style_name, 'custom-default') + + def test_with_local_style(self): + # Create an empty .style.yapf file in test_tmpdir + style_file = os.path.join(self.test_tmpdir, '.style.yapf') + open(style_file, 'w').close() + + test_filename = os.path.join(self.test_tmpdir, 'file.py') + self.assertEqual(style_file, + file_resources.GetDefaultStyleForDir(test_filename)) + + test_filename = os.path.join(self.test_tmpdir, 'dir1', 'file.py') + self.assertEqual(style_file, + file_resources.GetDefaultStyleForDir(test_filename)) + + def test_setup_config(self): + # An empty setup.cfg file should not be used + setup_config = os.path.join(self.test_tmpdir, 'setup.cfg') + open(setup_config, 'w').close() + + test_dir = os.path.join(self.test_tmpdir, 'dir1') + style_name = file_resources.GetDefaultStyleForDir(test_dir) + self.assertEqual(style_name, 'pep8') + + # One with a '[yapf]' section should be used + with open(setup_config, 'w') as f: + f.write('[yapf]\n') + self.assertEqual(setup_config, + file_resources.GetDefaultStyleForDir(test_dir)) + + def test_pyproject_toml(self): + # An empty pyproject.toml file should not be used + try: + import toml + except ImportError: + return + + pyproject_toml = os.path.join(self.test_tmpdir, 'pyproject.toml') + open(pyproject_toml, 'w').close() + + test_dir = os.path.join(self.test_tmpdir, 'dir1') + style_name = file_resources.GetDefaultStyleForDir(test_dir) + self.assertEqual(style_name, 'pep8') + + # One with a '[tool.yapf]' section should be used + with open(pyproject_toml, 'w') as f: + f.write('[tool.yapf]\n') + self.assertEqual(pyproject_toml, + file_resources.GetDefaultStyleForDir(test_dir)) + + def test_local_style_at_root(self): + # Test behavior of files located on the root, and under root. + rootdir = os.path.abspath(os.path.sep) + test_dir_at_root = os.path.join(rootdir, 'dir1') + test_dir_under_root = os.path.join(rootdir, 'dir1', 'dir2') + + # Fake placing only a style file at the root by mocking `os.path.exists`. + style_file = os.path.join(rootdir, '.style.yapf') + + def mock_exists_implementation(path): + return path == style_file + + with _exists_mocked_in_module(file_resources.os.path, + mock_exists_implementation): + # Both files should find the style file at the root. + default_style_at_root = file_resources.GetDefaultStyleForDir( + test_dir_at_root) + self.assertEqual(style_file, default_style_at_root) + default_style_under_root = file_resources.GetDefaultStyleForDir( + test_dir_under_root) + self.assertEqual(style_file, default_style_under_root) + + +def _touch_files(filenames): + for name in filenames: + open(name, 'a').close() + + +class GetCommandLineFilesTest(unittest.TestCase): + + def setUp(self): # pylint: disable=g-missing-super-call + self.test_tmpdir = tempfile.mkdtemp() + self.old_dir = os.getcwd() + + def tearDown(self): # pylint: disable=g-missing-super-call + os.chdir(self.old_dir) + shutil.rmtree(self.test_tmpdir) + + def _make_test_dir(self, name): + fullpath = os.path.normpath(os.path.join(self.test_tmpdir, name)) + os.makedirs(fullpath) + return fullpath + + def test_find_files_not_dirs(self): + tdir1 = self._make_test_dir('test1') + tdir2 = self._make_test_dir('test2') + file1 = os.path.join(tdir1, 'testfile1.py') + file2 = os.path.join(tdir2, 'testfile2.py') + _touch_files([file1, file2]) + + self.assertEqual( + file_resources.GetCommandLineFiles([file1, file2], + recursive=False, + exclude=None), [file1, file2]) + self.assertEqual( + file_resources.GetCommandLineFiles([file1, file2], + recursive=True, + exclude=None), [file1, file2]) + + def test_nonrecursive_find_in_dir(self): + tdir1 = self._make_test_dir('test1') + tdir2 = self._make_test_dir('test1/foo') + file1 = os.path.join(tdir1, 'testfile1.py') + file2 = os.path.join(tdir2, 'testfile2.py') + _touch_files([file1, file2]) + + self.assertRaises( + errors.YapfError, + file_resources.GetCommandLineFiles, + command_line_file_list=[tdir1], + recursive=False, + exclude=None) + + def test_recursive_find_in_dir(self): + tdir1 = self._make_test_dir('test1') + tdir2 = self._make_test_dir('test2/testinner/') + tdir3 = self._make_test_dir('test3/foo/bar/bas/xxx') + files = [ + os.path.join(tdir1, 'testfile1.py'), + os.path.join(tdir2, 'testfile2.py'), + os.path.join(tdir3, 'testfile3.py'), + ] + _touch_files(files) + + self.assertEqual( + sorted( + file_resources.GetCommandLineFiles([self.test_tmpdir], + recursive=True, + exclude=None)), sorted(files)) + + def test_recursive_find_in_dir_with_exclude(self): + tdir1 = self._make_test_dir('test1') + tdir2 = self._make_test_dir('test2/testinner/') + tdir3 = self._make_test_dir('test3/foo/bar/bas/xxx') + files = [ + os.path.join(tdir1, 'testfile1.py'), + os.path.join(tdir2, 'testfile2.py'), + os.path.join(tdir3, 'testfile3.py'), + ] + _touch_files(files) + + self.assertEqual( + sorted( + file_resources.GetCommandLineFiles([self.test_tmpdir], + recursive=True, + exclude=['*test*3.py'])), + sorted([ + os.path.join(tdir1, 'testfile1.py'), + os.path.join(tdir2, 'testfile2.py'), + ])) + + def test_find_with_excluded_hidden_dirs(self): + tdir1 = self._make_test_dir('.test1') + tdir2 = self._make_test_dir('test_2') + tdir3 = self._make_test_dir('test.3') + files = [ + os.path.join(tdir1, 'testfile1.py'), + os.path.join(tdir2, 'testfile2.py'), + os.path.join(tdir3, 'testfile3.py'), + ] + _touch_files(files) + + actual = file_resources.GetCommandLineFiles([self.test_tmpdir], + recursive=True, + exclude=['*.test1*']) + + self.assertEqual( + sorted(actual), + sorted([ + os.path.join(tdir2, 'testfile2.py'), + os.path.join(tdir3, 'testfile3.py'), + ])) + + def test_find_with_excluded_hidden_dirs_relative(self): + """Test find with excluded hidden dirs. + + A regression test against a specific case where a hidden directory (one + beginning with a period) is being excluded, but it is also an immediate + child of the current directory which has been specified in a relative + manner. + + At its core, the bug has to do with overzelous stripping of "./foo" so that + it removes too much from "./.foo" . + """ + tdir1 = self._make_test_dir('.test1') + tdir2 = self._make_test_dir('test_2') + tdir3 = self._make_test_dir('test.3') + files = [ + os.path.join(tdir1, 'testfile1.py'), + os.path.join(tdir2, 'testfile2.py'), + os.path.join(tdir3, 'testfile3.py'), + ] + _touch_files(files) + + # We must temporarily change the current directory, so that we test against + # patterns like ./.test1/file instead of /tmp/foo/.test1/file + with _restore_working_dir(): + + os.chdir(self.test_tmpdir) + actual = file_resources.GetCommandLineFiles( + [os.path.relpath(self.test_tmpdir)], + recursive=True, + exclude=['*.test1*']) + + self.assertEqual( + sorted(actual), + sorted([ + os.path.join( + os.path.relpath(self.test_tmpdir), os.path.basename(tdir2), + 'testfile2.py'), + os.path.join( + os.path.relpath(self.test_tmpdir), os.path.basename(tdir3), + 'testfile3.py'), + ])) + + def test_find_with_excluded_dirs(self): + tdir1 = self._make_test_dir('test1') + tdir2 = self._make_test_dir('test2/testinner/') + tdir3 = self._make_test_dir('test3/foo/bar/bas/xxx') + files = [ + os.path.join(tdir1, 'testfile1.py'), + os.path.join(tdir2, 'testfile2.py'), + os.path.join(tdir3, 'testfile3.py'), + ] + _touch_files(files) + + os.chdir(self.test_tmpdir) + + found = sorted( + file_resources.GetCommandLineFiles(['test1', 'test2', 'test3'], + recursive=True, + exclude=[ + 'test1', + 'test2/testinner/', + ])) + + self.assertEqual( + found, ['test3/foo/bar/bas/xxx/testfile3.py'.replace("/", os.path.sep)]) + + found = sorted( + file_resources.GetCommandLineFiles(['.'], + recursive=True, + exclude=[ + 'test1', + 'test3', + ])) + + self.assertEqual( + found, ['./test2/testinner/testfile2.py'.replace("/", os.path.sep)]) + + def test_find_with_excluded_current_dir(self): + with self.assertRaises(errors.YapfError): + file_resources.GetCommandLineFiles([], False, exclude=['./z']) + + +class IsPythonFileTest(unittest.TestCase): + + def setUp(self): # pylint: disable=g-missing-super-call + self.test_tmpdir = tempfile.mkdtemp() + + def tearDown(self): # pylint: disable=g-missing-super-call + shutil.rmtree(self.test_tmpdir) + + def test_with_py_extension(self): + file1 = os.path.join(self.test_tmpdir, 'testfile1.py') + self.assertTrue(file_resources.IsPythonFile(file1)) + + def test_empty_without_py_extension(self): + file1 = os.path.join(self.test_tmpdir, 'testfile1') + self.assertFalse(file_resources.IsPythonFile(file1)) + file2 = os.path.join(self.test_tmpdir, 'testfile1.rb') + self.assertFalse(file_resources.IsPythonFile(file2)) + + def test_python_shebang(self): + file1 = os.path.join(self.test_tmpdir, 'testfile1') + with open(file1, 'w') as f: + f.write(u'#!/usr/bin/python\n') + self.assertTrue(file_resources.IsPythonFile(file1)) + + file2 = os.path.join(self.test_tmpdir, 'testfile2.run') + with open(file2, 'w') as f: + f.write(u'#! /bin/python2\n') + self.assertTrue(file_resources.IsPythonFile(file1)) + + def test_with_latin_encoding(self): + file1 = os.path.join(self.test_tmpdir, 'testfile1') + with py3compat.open_with_encoding(file1, mode='w', encoding='latin-1') as f: + f.write(u'#! /bin/python2\n') + self.assertTrue(file_resources.IsPythonFile(file1)) + + def test_with_invalid_encoding(self): + file1 = os.path.join(self.test_tmpdir, 'testfile1') + with open(file1, 'w') as f: + f.write(u'#! /bin/python2\n') + f.write(u'# -*- coding: iso-3-14159 -*-\n') + self.assertFalse(file_resources.IsPythonFile(file1)) + + +class IsIgnoredTest(unittest.TestCase): + + def test_root_path(self): + self.assertTrue(file_resources.IsIgnored('media', ['media'])) + self.assertFalse(file_resources.IsIgnored('media', ['media/*'])) + + def test_sub_path(self): + self.assertTrue(file_resources.IsIgnored('media/a', ['*/a'])) + self.assertTrue(file_resources.IsIgnored('media/b', ['media/*'])) + self.assertTrue(file_resources.IsIgnored('media/b/c', ['*/*/c'])) + + def test_trailing_slash(self): + self.assertTrue(file_resources.IsIgnored('z', ['z'])) + self.assertTrue(file_resources.IsIgnored('z', ['z' + os.path.sep])) + + +class BufferedByteStream(object): + + def __init__(self): + self.stream = py3compat.BytesIO() + + def getvalue(self): # pylint: disable=invalid-name + return self.stream.getvalue().decode('utf-8') + + @property + def buffer(self): + return self.stream + + +class WriteReformattedCodeTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): # pylint: disable=g-missing-super-call + cls.test_tmpdir = tempfile.mkdtemp() + + @classmethod + def tearDownClass(cls): # pylint: disable=g-missing-super-call + shutil.rmtree(cls.test_tmpdir) + + def test_write_to_file(self): + s = u'foobar\n' + with utils.NamedTempFile(dirname=self.test_tmpdir) as (f, fname): + file_resources.WriteReformattedCode( + fname, s, in_place=True, encoding='utf-8') + f.flush() + + with open(fname) as f2: + self.assertEqual(f2.read(), s) + + def test_write_to_stdout(self): + s = u'foobar' + stream = BufferedByteStream() if py3compat.PY3 else py3compat.StringIO() + with utils.stdout_redirector(stream): + file_resources.WriteReformattedCode( + None, s, in_place=False, encoding='utf-8') + self.assertEqual(stream.getvalue(), s) + + def test_write_encoded_to_stdout(self): + s = '\ufeff# -*- coding: utf-8 -*-\nresult = "passed"\n' # pylint: disable=anomalous-unicode-escape-in-string + stream = BufferedByteStream() if py3compat.PY3 else py3compat.StringIO() + with utils.stdout_redirector(stream): + file_resources.WriteReformattedCode( + None, s, in_place=False, encoding='utf-8') + self.assertEqual(stream.getvalue(), s) + + +class LineEndingTest(unittest.TestCase): + + def test_line_ending_linefeed(self): + lines = ['spam\n', 'spam\n'] + actual = file_resources.LineEnding(lines) + self.assertEqual(actual, '\n') + + def test_line_ending_carriage_return(self): + lines = ['spam\r', 'spam\r'] + actual = file_resources.LineEnding(lines) + self.assertEqual(actual, '\r') + + def test_line_ending_combo(self): + lines = ['spam\r\n', 'spam\r\n'] + actual = file_resources.LineEnding(lines) + self.assertEqual(actual, '\r\n') + + def test_line_ending_weighted(self): + lines = [ + 'spam\n', + 'spam\n', + 'spam\r', + 'spam\r\n', + ] + actual = file_resources.LineEnding(lines) + self.assertEqual(actual, '\n') + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/format_decision_state_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/format_decision_state_test.py new file mode 100644 index 00000000..39e7e8e0 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/format_decision_state_test.py @@ -0,0 +1,145 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.format_decision_state.""" + +import textwrap +import unittest + +from yapf.yapflib import format_decision_state +from yapf.yapflib import pytree_utils +from yapf.yapflib import style +from yapf.yapflib import unwrapped_line + +from yapftests import yapf_test_helper + + +class FormatDecisionStateTest(yapf_test_helper.YAPFTest): + + @classmethod + def setUpClass(cls): + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testSimpleFunctionDefWithNoSplitting(self): + code = textwrap.dedent(r""" + def f(a, b): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + uwline = unwrapped_line.UnwrappedLine(0, _FilterLine(uwlines[0])) + uwline.CalculateFormattingInformation() + + # Add: 'f' + state = format_decision_state.FormatDecisionState(uwline, 0) + state.MoveStateToNextToken() + self.assertEqual('f', state.next_token.value) + self.assertFalse(state.CanSplit(False)) + + # Add: '(' + state.AddTokenToState(False, True) + self.assertEqual('(', state.next_token.value) + self.assertFalse(state.CanSplit(False)) + self.assertFalse(state.MustSplit()) + + # Add: 'a' + state.AddTokenToState(False, True) + self.assertEqual('a', state.next_token.value) + self.assertTrue(state.CanSplit(False)) + self.assertFalse(state.MustSplit()) + + # Add: ',' + state.AddTokenToState(False, True) + self.assertEqual(',', state.next_token.value) + self.assertFalse(state.CanSplit(False)) + self.assertFalse(state.MustSplit()) + + # Add: 'b' + state.AddTokenToState(False, True) + self.assertEqual('b', state.next_token.value) + self.assertTrue(state.CanSplit(False)) + self.assertFalse(state.MustSplit()) + + # Add: ')' + state.AddTokenToState(False, True) + self.assertEqual(')', state.next_token.value) + self.assertTrue(state.CanSplit(False)) + self.assertFalse(state.MustSplit()) + + # Add: ':' + state.AddTokenToState(False, True) + self.assertEqual(':', state.next_token.value) + self.assertFalse(state.CanSplit(False)) + self.assertFalse(state.MustSplit()) + + clone = state.Clone() + self.assertEqual(repr(state), repr(clone)) + + def testSimpleFunctionDefWithSplitting(self): + code = textwrap.dedent(r""" + def f(a, b): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + uwline = unwrapped_line.UnwrappedLine(0, _FilterLine(uwlines[0])) + uwline.CalculateFormattingInformation() + + # Add: 'f' + state = format_decision_state.FormatDecisionState(uwline, 0) + state.MoveStateToNextToken() + self.assertEqual('f', state.next_token.value) + self.assertFalse(state.CanSplit(False)) + + # Add: '(' + state.AddTokenToState(True, True) + self.assertEqual('(', state.next_token.value) + self.assertFalse(state.CanSplit(False)) + + # Add: 'a' + state.AddTokenToState(True, True) + self.assertEqual('a', state.next_token.value) + self.assertTrue(state.CanSplit(False)) + + # Add: ',' + state.AddTokenToState(True, True) + self.assertEqual(',', state.next_token.value) + self.assertFalse(state.CanSplit(False)) + + # Add: 'b' + state.AddTokenToState(True, True) + self.assertEqual('b', state.next_token.value) + self.assertTrue(state.CanSplit(False)) + + # Add: ')' + state.AddTokenToState(True, True) + self.assertEqual(')', state.next_token.value) + self.assertTrue(state.CanSplit(False)) + + # Add: ':' + state.AddTokenToState(True, True) + self.assertEqual(':', state.next_token.value) + self.assertFalse(state.CanSplit(False)) + + clone = state.Clone() + self.assertEqual(repr(state), repr(clone)) + + +def _FilterLine(uwline): + """Filter out nonsemantic tokens from the UnwrappedLines.""" + return [ + ft for ft in uwline.tokens + if ft.name not in pytree_utils.NONSEMANTIC_TOKENS + ] + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/format_token_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/format_token_test.py new file mode 100644 index 00000000..b4c71510 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/format_token_test.py @@ -0,0 +1,88 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.format_token.""" + +import unittest + +from lib2to3 import pytree +from lib2to3.pgen2 import token + +from yapf.yapflib import format_token + + +class TabbedContinuationAlignPaddingTest(unittest.TestCase): + + def testSpace(self): + align_style = 'SPACE' + + pad = format_token._TabbedContinuationAlignPadding(0, align_style, 2) + self.assertEqual(pad, '') + + pad = format_token._TabbedContinuationAlignPadding(2, align_style, 2) + self.assertEqual(pad, ' ' * 2) + + pad = format_token._TabbedContinuationAlignPadding(5, align_style, 2) + self.assertEqual(pad, ' ' * 5) + + def testFixed(self): + align_style = 'FIXED' + + pad = format_token._TabbedContinuationAlignPadding(0, align_style, 4) + self.assertEqual(pad, '') + + pad = format_token._TabbedContinuationAlignPadding(2, align_style, 4) + self.assertEqual(pad, '\t') + + pad = format_token._TabbedContinuationAlignPadding(5, align_style, 4) + self.assertEqual(pad, '\t' * 2) + + def testVAlignRight(self): + align_style = 'VALIGN-RIGHT' + + pad = format_token._TabbedContinuationAlignPadding(0, align_style, 4) + self.assertEqual(pad, '') + + pad = format_token._TabbedContinuationAlignPadding(2, align_style, 4) + self.assertEqual(pad, '\t') + + pad = format_token._TabbedContinuationAlignPadding(4, align_style, 4) + self.assertEqual(pad, '\t') + + pad = format_token._TabbedContinuationAlignPadding(5, align_style, 4) + self.assertEqual(pad, '\t' * 2) + + +class FormatTokenTest(unittest.TestCase): + + def testSimple(self): + tok = format_token.FormatToken(pytree.Leaf(token.STRING, "'hello world'")) + self.assertEqual("FormatToken(name=STRING, value='hello world', lineno=0)", + str(tok)) + self.assertTrue(tok.is_string) + + tok = format_token.FormatToken(pytree.Leaf(token.COMMENT, '# A comment')) + self.assertEqual('FormatToken(name=COMMENT, value=# A comment, lineno=0)', + str(tok)) + self.assertTrue(tok.is_comment) + + def testIsMultilineString(self): + tok = format_token.FormatToken(pytree.Leaf(token.STRING, '"""hello"""')) + self.assertTrue(tok.is_multiline_string) + + tok = format_token.FormatToken(pytree.Leaf(token.STRING, 'r"""hello"""')) + self.assertTrue(tok.is_multiline_string) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/line_joiner_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/line_joiner_test.py new file mode 100644 index 00000000..6501bc88 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/line_joiner_test.py @@ -0,0 +1,82 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.line_joiner.""" + +import textwrap +import unittest + +from yapf.yapflib import line_joiner +from yapf.yapflib import style + +from yapftests import yapf_test_helper + + +class LineJoinerTest(yapf_test_helper.YAPFTest): + + @classmethod + def setUpClass(cls): + style.SetGlobalStyle(style.CreatePEP8Style()) + + def _CheckLineJoining(self, code, join_lines): + """Check that the given UnwrappedLines are joined as expected. + + Arguments: + code: The code to check to see if we can join it. + join_lines: True if we expect the lines to be joined. + """ + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(line_joiner.CanMergeMultipleLines(uwlines), join_lines) + + def testSimpleSingleLineStatement(self): + code = textwrap.dedent(u"""\ + if isinstance(a, int): continue + """) + self._CheckLineJoining(code, join_lines=True) + + def testSimpleMultipleLineStatement(self): + code = textwrap.dedent(u"""\ + if isinstance(b, int): + continue + """) + self._CheckLineJoining(code, join_lines=False) + + def testSimpleMultipleLineComplexStatement(self): + code = textwrap.dedent(u"""\ + if isinstance(c, int): + while True: + continue + """) + self._CheckLineJoining(code, join_lines=False) + + def testSimpleMultipleLineStatementWithComment(self): + code = textwrap.dedent(u"""\ + if isinstance(d, int): continue # We're pleased that d's an int. + """) + self._CheckLineJoining(code, join_lines=True) + + def testSimpleMultipleLineStatementWithLargeIndent(self): + code = textwrap.dedent(u"""\ + if isinstance(e, int): continue + """) + self._CheckLineJoining(code, join_lines=True) + + def testOverColumnLimit(self): + code = textwrap.dedent(u"""\ + if instance(bbbbbbbbbbbbbbbbbbbbbbbbb, int): cccccccccccccccccccccccccc = ddddddddddddddddddddd + """) + self._CheckLineJoining(code, join_lines=False) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/main_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/main_test.py new file mode 100644 index 00000000..94daaaa9 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/main_test.py @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.__init__.main.""" + +from contextlib import contextmanager +import sys +import unittest +import yapf + +from yapf.yapflib import py3compat + + +class IO(object): + """IO is a thin wrapper around StringIO. + + This is strictly to wrap the Python 3 StringIO object so that it can supply a + "buffer" attribute. + """ + + class Buffer(object): + + def __init__(self): + self.string_io = py3compat.StringIO() + + def write(self, s): + if py3compat.PY3 and isinstance(s, bytes): + s = str(s, 'utf-8') + self.string_io.write(s) + + def getvalue(self): + return self.string_io.getvalue() + + def __init__(self): + self.buffer = self.Buffer() + + def write(self, s): + self.buffer.write(s) + + def getvalue(self): + return self.buffer.getvalue() + + +@contextmanager +def captured_output(): + new_out, new_err = IO(), IO() + old_out, old_err = sys.stdout, sys.stderr + try: + sys.stdout, sys.stderr = new_out, new_err + yield sys.stdout, sys.stderr + finally: + sys.stdout, sys.stderr = old_out, old_err + + +@contextmanager +def patched_input(code): + """Monkey patch code as though it were coming from stdin.""" + + def lines(): + for line in code.splitlines(): + yield line + raise EOFError() + + def patch_raw_input(lines=lines()): + return next(lines) + + try: + orig_raw_import = yapf.py3compat.raw_input + yapf.py3compat.raw_input = patch_raw_input + yield + finally: + yapf.py3compat.raw_input = orig_raw_import + + +class RunMainTest(unittest.TestCase): + + def testShouldHandleYapfError(self): + """run_main should handle YapfError and sys.exit(1).""" + expected_message = 'yapf: Input filenames did not match any python files\n' + sys.argv = ['yapf', 'foo.c'] + with captured_output() as (out, err): + with self.assertRaises(SystemExit): + yapf.run_main() + self.assertEqual(out.getvalue(), '') + self.assertEqual(err.getvalue(), expected_message) + + +class MainTest(unittest.TestCase): + + def testNoPythonFilesMatched(self): + with self.assertRaisesRegexp(yapf.errors.YapfError, + 'did not match any python files'): + yapf.main(['yapf', 'foo.c']) + + def testEchoInput(self): + code = 'a = 1\nb = 2\n' + with patched_input(code): + with captured_output() as (out, _): + ret = yapf.main([]) + self.assertEqual(ret, 0) + self.assertEqual(out.getvalue(), code) + + def testEchoInputWithStyle(self): + code = 'def f(a = 1):\n return 2*a\n' + yapf_code = 'def f(a=1):\n return 2 * a\n' + with patched_input(code): + with captured_output() as (out, _): + ret = yapf.main(['-', '--style=yapf']) + self.assertEqual(ret, 0) + self.assertEqual(out.getvalue(), yapf_code) + + def testEchoBadInput(self): + bad_syntax = ' a = 1\n' + with patched_input(bad_syntax): + with captured_output() as (_, _): + with self.assertRaisesRegexp(SyntaxError, 'unexpected indent'): + yapf.main([]) + + def testHelp(self): + with captured_output() as (out, _): + ret = yapf.main(['-', '--style-help', '--style=pep8']) + self.assertEqual(ret, 0) + help_message = out.getvalue() + self.assertIn('indent_width=4', help_message) + self.assertIn('The number of spaces required before a trailing comment.', + help_message) + + def testVersion(self): + with captured_output() as (out, _): + ret = yapf.main(['-', '--version']) + self.assertEqual(ret, 0) + version = 'yapf {}\n'.format(yapf.__version__) + self.assertEqual(version, out.getvalue()) diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/pytree_unwrapper_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/pytree_unwrapper_test.py new file mode 100644 index 00000000..f95f3666 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/pytree_unwrapper_test.py @@ -0,0 +1,356 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.pytree_unwrapper.""" + +import textwrap +import unittest + +from yapf.yapflib import pytree_utils + +from yapftests import yapf_test_helper + + +class PytreeUnwrapperTest(yapf_test_helper.YAPFTest): + + def _CheckUnwrappedLines(self, uwlines, list_of_expected): + """Check that the given UnwrappedLines match expectations. + + Args: + uwlines: list of UnwrappedLine + list_of_expected: list of (depth, values) pairs. Non-semantic tokens are + filtered out from the expected values. + """ + actual = [] + for uwl in uwlines: + filtered_values = [ + ft.value + for ft in uwl.tokens + if ft.name not in pytree_utils.NONSEMANTIC_TOKENS + ] + actual.append((uwl.depth, filtered_values)) + + self.assertEqual(list_of_expected, actual) + + def testSimpleFileScope(self): + code = textwrap.dedent(r""" + x = 1 + # a comment + y = 2 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['x', '=', '1']), + (0, ['# a comment']), + (0, ['y', '=', '2']), + ]) + + def testSimpleMultilineStatement(self): + code = textwrap.dedent(r""" + y = (1 + + x) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['y', '=', '(', '1', '+', 'x', ')']), + ]) + + def testFileScopeWithInlineComment(self): + code = textwrap.dedent(r""" + x = 1 # a comment + y = 2 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['x', '=', '1', '# a comment']), + (0, ['y', '=', '2']), + ]) + + def testSimpleIf(self): + code = textwrap.dedent(r""" + if foo: + x = 1 + y = 2 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['if', 'foo', ':']), + (1, ['x', '=', '1']), + (1, ['y', '=', '2']), + ]) + + def testSimpleIfWithComments(self): + code = textwrap.dedent(r""" + # c1 + if foo: # c2 + x = 1 + y = 2 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['# c1']), + (0, ['if', 'foo', ':', '# c2']), + (1, ['x', '=', '1']), + (1, ['y', '=', '2']), + ]) + + def testIfWithCommentsInside(self): + code = textwrap.dedent(r""" + if foo: + # c1 + x = 1 # c2 + # c3 + y = 2 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['if', 'foo', ':']), + (1, ['# c1']), + (1, ['x', '=', '1', '# c2']), + (1, ['# c3']), + (1, ['y', '=', '2']), + ]) + + def testIfElifElse(self): + code = textwrap.dedent(r""" + if x: + x = 1 # c1 + elif y: # c2 + y = 1 + else: + # c3 + z = 1 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['if', 'x', ':']), + (1, ['x', '=', '1', '# c1']), + (0, ['elif', 'y', ':', '# c2']), + (1, ['y', '=', '1']), + (0, ['else', ':']), + (1, ['# c3']), + (1, ['z', '=', '1']), + ]) + + def testNestedCompoundTwoLevel(self): + code = textwrap.dedent(r""" + if x: + x = 1 # c1 + while t: + # c2 + j = 1 + k = 1 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['if', 'x', ':']), + (1, ['x', '=', '1', '# c1']), + (1, ['while', 't', ':']), + (2, ['# c2']), + (2, ['j', '=', '1']), + (1, ['k', '=', '1']), + ]) + + def testSimpleWhile(self): + code = textwrap.dedent(r""" + while x > 1: # c1 + # c2 + x = 1 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['while', 'x', '>', '1', ':', '# c1']), + (1, ['# c2']), + (1, ['x', '=', '1']), + ]) + + def testSimpleTry(self): + code = textwrap.dedent(r""" + try: + pass + except: + pass + except: + pass + else: + pass + finally: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['try', ':']), + (1, ['pass']), + (0, ['except', ':']), + (1, ['pass']), + (0, ['except', ':']), + (1, ['pass']), + (0, ['else', ':']), + (1, ['pass']), + (0, ['finally', ':']), + (1, ['pass']), + ]) + + def testSimpleFuncdef(self): + code = textwrap.dedent(r""" + def foo(x): # c1 + # c2 + return x + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['def', 'foo', '(', 'x', ')', ':', '# c1']), + (1, ['# c2']), + (1, ['return', 'x']), + ]) + + def testTwoFuncDefs(self): + code = textwrap.dedent(r""" + def foo(x): # c1 + # c2 + return x + + def bar(): # c3 + # c4 + return x + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['def', 'foo', '(', 'x', ')', ':', '# c1']), + (1, ['# c2']), + (1, ['return', 'x']), + (0, ['def', 'bar', '(', ')', ':', '# c3']), + (1, ['# c4']), + (1, ['return', 'x']), + ]) + + def testSimpleClassDef(self): + code = textwrap.dedent(r""" + class Klass: # c1 + # c2 + p = 1 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['class', 'Klass', ':', '# c1']), + (1, ['# c2']), + (1, ['p', '=', '1']), + ]) + + def testSingleLineStmtInFunc(self): + code = textwrap.dedent(r""" + def f(): return 37 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['def', 'f', '(', ')', ':']), + (1, ['return', '37']), + ]) + + def testMultipleComments(self): + code = textwrap.dedent(r""" + # Comment #1 + + # Comment #2 + def f(): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [ + (0, ['# Comment #1']), + (0, ['# Comment #2']), + (0, ['def', 'f', '(', ')', ':']), + (1, ['pass']), + ]) + + def testSplitListWithComment(self): + code = textwrap.dedent(r""" + a = [ + 'a', + 'b', + 'c', # hello world + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckUnwrappedLines(uwlines, [(0, [ + 'a', '=', '[', "'a'", ',', "'b'", ',', "'c'", ',', '# hello world', ']' + ])]) + + +class MatchBracketsTest(yapf_test_helper.YAPFTest): + + def _CheckMatchingBrackets(self, uwlines, list_of_expected): + """Check that the tokens have the expected matching bracket. + + Arguments: + uwlines: list of UnwrappedLine. + list_of_expected: list of (index, index) pairs. The matching brackets at + the indexes need to match. Non-semantic tokens are filtered out from the + expected values. + """ + actual = [] + for uwl in uwlines: + filtered_values = [(ft, ft.matching_bracket) + for ft in uwl.tokens + if ft.name not in pytree_utils.NONSEMANTIC_TOKENS] + if filtered_values: + actual.append(filtered_values) + + for index, bracket_list in enumerate(list_of_expected): + uwline = actual[index] + if not bracket_list: + for value in uwline: + self.assertIsNone(value[1]) + else: + for open_bracket, close_bracket in bracket_list: + self.assertEqual(uwline[open_bracket][0], uwline[close_bracket][1]) + self.assertEqual(uwline[close_bracket][0], uwline[open_bracket][1]) + + def testFunctionDef(self): + code = textwrap.dedent("""\ + def foo(a, b=['w','d'], c=[42, 37]): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckMatchingBrackets(uwlines, [ + [(2, 20), (7, 11), (15, 19)], + [], + ]) + + def testDecorator(self): + code = textwrap.dedent("""\ + @bar() + def foo(a, b, c): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckMatchingBrackets(uwlines, [ + [(2, 3)], + [(2, 8)], + [], + ]) + + def testClassDef(self): + code = textwrap.dedent("""\ + class A(B, C, D): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckMatchingBrackets(uwlines, [ + [(2, 8)], + [], + ]) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/pytree_utils_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/pytree_utils_test.py new file mode 100644 index 00000000..3b9fde7f --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/pytree_utils_test.py @@ -0,0 +1,205 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.pytree_utils.""" + +import unittest + +from lib2to3 import pygram +from lib2to3 import pytree +from lib2to3.pgen2 import token + +from yapf.yapflib import pytree_utils + +# More direct access to the symbol->number mapping living within the grammar +# module. +_GRAMMAR_SYMBOL2NUMBER = pygram.python_grammar.symbol2number + +_FOO = 'foo' +_FOO1 = 'foo1' +_FOO2 = 'foo2' +_FOO3 = 'foo3' +_FOO4 = 'foo4' +_FOO5 = 'foo5' + + +class NodeNameTest(unittest.TestCase): + + def testNodeNameForLeaf(self): + leaf = pytree.Leaf(token.LPAR, '(') + self.assertEqual('LPAR', pytree_utils.NodeName(leaf)) + + def testNodeNameForNode(self): + leaf = pytree.Leaf(token.LPAR, '(') + node = pytree.Node(pygram.python_grammar.symbol2number['suite'], [leaf]) + self.assertEqual('suite', pytree_utils.NodeName(node)) + + +class ParseCodeToTreeTest(unittest.TestCase): + + def testParseCodeToTree(self): + # Since ParseCodeToTree is a thin wrapper around underlying lib2to3 + # functionality, only a sanity test here... + tree = pytree_utils.ParseCodeToTree('foo = 2\n') + self.assertEqual('file_input', pytree_utils.NodeName(tree)) + self.assertEqual(2, len(tree.children)) + self.assertEqual('simple_stmt', pytree_utils.NodeName(tree.children[0])) + + def testPrintFunctionToTree(self): + tree = pytree_utils.ParseCodeToTree( + 'print("hello world", file=sys.stderr)\n') + self.assertEqual('file_input', pytree_utils.NodeName(tree)) + self.assertEqual(2, len(tree.children)) + self.assertEqual('simple_stmt', pytree_utils.NodeName(tree.children[0])) + + def testPrintStatementToTree(self): + tree = pytree_utils.ParseCodeToTree('print "hello world"\n') + self.assertEqual('file_input', pytree_utils.NodeName(tree)) + self.assertEqual(2, len(tree.children)) + self.assertEqual('simple_stmt', pytree_utils.NodeName(tree.children[0])) + + def testClassNotLocal(self): + tree = pytree_utils.ParseCodeToTree('class nonlocal: pass\n') + self.assertEqual('file_input', pytree_utils.NodeName(tree)) + self.assertEqual(2, len(tree.children)) + self.assertEqual('classdef', pytree_utils.NodeName(tree.children[0])) + + +class InsertNodesBeforeAfterTest(unittest.TestCase): + + def _BuildSimpleTree(self): + # Builds a simple tree we can play with in the tests. + # The tree looks like this: + # + # suite: + # LPAR + # LPAR + # simple_stmt: + # NAME('foo') + # + lpar1 = pytree.Leaf(token.LPAR, '(') + lpar2 = pytree.Leaf(token.LPAR, '(') + simple_stmt = pytree.Node(_GRAMMAR_SYMBOL2NUMBER['simple_stmt'], + [pytree.Leaf(token.NAME, 'foo')]) + return pytree.Node(_GRAMMAR_SYMBOL2NUMBER['suite'], + [lpar1, lpar2, simple_stmt]) + + def _MakeNewNodeRPAR(self): + return pytree.Leaf(token.RPAR, ')') + + def setUp(self): + self._simple_tree = self._BuildSimpleTree() + + def testInsertNodesBefore(self): + # Insert before simple_stmt and make sure it went to the right place + pytree_utils.InsertNodesBefore([self._MakeNewNodeRPAR()], + self._simple_tree.children[2]) + self.assertEqual(4, len(self._simple_tree.children)) + self.assertEqual('RPAR', + pytree_utils.NodeName(self._simple_tree.children[2])) + self.assertEqual('simple_stmt', + pytree_utils.NodeName(self._simple_tree.children[3])) + + def testInsertNodesBeforeFirstChild(self): + # Insert before the first child of its parent + simple_stmt = self._simple_tree.children[2] + foo_child = simple_stmt.children[0] + pytree_utils.InsertNodesBefore([self._MakeNewNodeRPAR()], foo_child) + self.assertEqual(3, len(self._simple_tree.children)) + self.assertEqual(2, len(simple_stmt.children)) + self.assertEqual('RPAR', pytree_utils.NodeName(simple_stmt.children[0])) + self.assertEqual('NAME', pytree_utils.NodeName(simple_stmt.children[1])) + + def testInsertNodesAfter(self): + # Insert after and make sure it went to the right place + pytree_utils.InsertNodesAfter([self._MakeNewNodeRPAR()], + self._simple_tree.children[2]) + self.assertEqual(4, len(self._simple_tree.children)) + self.assertEqual('simple_stmt', + pytree_utils.NodeName(self._simple_tree.children[2])) + self.assertEqual('RPAR', + pytree_utils.NodeName(self._simple_tree.children[3])) + + def testInsertNodesAfterLastChild(self): + # Insert after the last child of its parent + simple_stmt = self._simple_tree.children[2] + foo_child = simple_stmt.children[0] + pytree_utils.InsertNodesAfter([self._MakeNewNodeRPAR()], foo_child) + self.assertEqual(3, len(self._simple_tree.children)) + self.assertEqual(2, len(simple_stmt.children)) + self.assertEqual('NAME', pytree_utils.NodeName(simple_stmt.children[0])) + self.assertEqual('RPAR', pytree_utils.NodeName(simple_stmt.children[1])) + + def testInsertNodesWhichHasParent(self): + # Try to insert an existing tree node into another place and fail. + with self.assertRaises(RuntimeError): + pytree_utils.InsertNodesAfter([self._simple_tree.children[1]], + self._simple_tree.children[0]) + + +class AnnotationsTest(unittest.TestCase): + + def setUp(self): + self._leaf = pytree.Leaf(token.LPAR, '(') + self._node = pytree.Node(_GRAMMAR_SYMBOL2NUMBER['simple_stmt'], + [pytree.Leaf(token.NAME, 'foo')]) + + def testGetWhenNone(self): + self.assertIsNone(pytree_utils.GetNodeAnnotation(self._leaf, _FOO)) + + def testSetWhenNone(self): + pytree_utils.SetNodeAnnotation(self._leaf, _FOO, 20) + self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO), 20) + + def testSetAgain(self): + pytree_utils.SetNodeAnnotation(self._leaf, _FOO, 20) + self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO), 20) + pytree_utils.SetNodeAnnotation(self._leaf, _FOO, 30) + self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO), 30) + + def testMultiple(self): + pytree_utils.SetNodeAnnotation(self._leaf, _FOO, 20) + pytree_utils.SetNodeAnnotation(self._leaf, _FOO1, 1) + pytree_utils.SetNodeAnnotation(self._leaf, _FOO2, 2) + pytree_utils.SetNodeAnnotation(self._leaf, _FOO3, 3) + pytree_utils.SetNodeAnnotation(self._leaf, _FOO4, 4) + pytree_utils.SetNodeAnnotation(self._leaf, _FOO5, 5) + + self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO), 20) + self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO1), 1) + self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO2), 2) + self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO3), 3) + self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO4), 4) + self.assertEqual(pytree_utils.GetNodeAnnotation(self._leaf, _FOO5), 5) + + def testSubtype(self): + pytree_utils.AppendNodeAnnotation(self._leaf, + pytree_utils.Annotation.SUBTYPE, _FOO) + + self.assertSetEqual( + pytree_utils.GetNodeAnnotation(self._leaf, + pytree_utils.Annotation.SUBTYPE), {_FOO}) + + pytree_utils.RemoveSubtypeAnnotation(self._leaf, _FOO) + + self.assertSetEqual( + pytree_utils.GetNodeAnnotation(self._leaf, + pytree_utils.Annotation.SUBTYPE), set()) + + def testSetOnNode(self): + pytree_utils.SetNodeAnnotation(self._node, _FOO, 20) + self.assertEqual(pytree_utils.GetNodeAnnotation(self._node, _FOO), 20) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/pytree_visitor_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/pytree_visitor_test.py new file mode 100644 index 00000000..1908249d --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/pytree_visitor_test.py @@ -0,0 +1,120 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.pytree_visitor.""" + +import unittest + +from yapf.yapflib import py3compat +from yapf.yapflib import pytree_utils +from yapf.yapflib import pytree_visitor + + +class _NodeNameCollector(pytree_visitor.PyTreeVisitor): + """A tree visitor that collects the names of all tree nodes into a list. + + Attributes: + all_node_names: collected list of the names, available when the traversal + is over. + name_node_values: collects a list of NAME leaves (in addition to those going + into all_node_names). + """ + + def __init__(self): + self.all_node_names = [] + self.name_node_values = [] + + def DefaultNodeVisit(self, node): + self.all_node_names.append(pytree_utils.NodeName(node)) + super(_NodeNameCollector, self).DefaultNodeVisit(node) + + def DefaultLeafVisit(self, leaf): + self.all_node_names.append(pytree_utils.NodeName(leaf)) + + def Visit_NAME(self, leaf): + self.name_node_values.append(leaf.value) + self.DefaultLeafVisit(leaf) + + +_VISITOR_TEST_SIMPLE_CODE = r""" +foo = bar +baz = x +""" + +_VISITOR_TEST_NESTED_CODE = r""" +if x: + if y: + return z +""" + + +class PytreeVisitorTest(unittest.TestCase): + + def testCollectAllNodeNamesSimpleCode(self): + tree = pytree_utils.ParseCodeToTree(_VISITOR_TEST_SIMPLE_CODE) + collector = _NodeNameCollector() + collector.Visit(tree) + expected_names = [ + 'file_input', + 'simple_stmt', 'expr_stmt', 'NAME', 'EQUAL', 'NAME', 'NEWLINE', + 'simple_stmt', 'expr_stmt', 'NAME', 'EQUAL', 'NAME', 'NEWLINE', + 'ENDMARKER', + ] # yapf: disable + self.assertEqual(expected_names, collector.all_node_names) + + expected_name_node_values = ['foo', 'bar', 'baz', 'x'] + self.assertEqual(expected_name_node_values, collector.name_node_values) + + def testCollectAllNodeNamesNestedCode(self): + tree = pytree_utils.ParseCodeToTree(_VISITOR_TEST_NESTED_CODE) + collector = _NodeNameCollector() + collector.Visit(tree) + expected_names = [ + 'file_input', + 'if_stmt', 'NAME', 'NAME', 'COLON', + 'suite', 'NEWLINE', + 'INDENT', 'if_stmt', 'NAME', 'NAME', 'COLON', 'suite', 'NEWLINE', + 'INDENT', 'simple_stmt', 'return_stmt', 'NAME', 'NAME', 'NEWLINE', + 'DEDENT', 'DEDENT', 'ENDMARKER', + ] # yapf: disable + self.assertEqual(expected_names, collector.all_node_names) + + expected_name_node_values = ['if', 'x', 'if', 'y', 'return', 'z'] + self.assertEqual(expected_name_node_values, collector.name_node_values) + + def testDumper(self): + # PyTreeDumper is mainly a debugging utility, so only do basic sanity + # checking. + tree = pytree_utils.ParseCodeToTree(_VISITOR_TEST_SIMPLE_CODE) + stream = py3compat.StringIO() + pytree_visitor.PyTreeDumper(target_stream=stream).Visit(tree) + + dump_output = stream.getvalue() + self.assertIn('file_input [3 children]', dump_output) + self.assertIn("NAME(Leaf(NAME, 'foo'))", dump_output) + self.assertIn("EQUAL(Leaf(EQUAL, '='))", dump_output) + + def testDumpPyTree(self): + # Similar sanity checking for the convenience wrapper DumpPyTree + tree = pytree_utils.ParseCodeToTree(_VISITOR_TEST_SIMPLE_CODE) + stream = py3compat.StringIO() + pytree_visitor.DumpPyTree(tree, target_stream=stream) + + dump_output = stream.getvalue() + self.assertIn('file_input [3 children]', dump_output) + self.assertIn("NAME(Leaf(NAME, 'foo'))", dump_output) + self.assertIn("EQUAL(Leaf(EQUAL, '='))", dump_output) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_basic_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_basic_test.py new file mode 100644 index 00000000..a67e4c47 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_basic_test.py @@ -0,0 +1,3140 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Basic tests for yapf.reformatter.""" + +import textwrap +import unittest + +from yapf.yapflib import py3compat +from yapf.yapflib import reformatter +from yapf.yapflib import style + +from yapftests import yapf_test_helper + + +class BasicReformatterTest(yapf_test_helper.YAPFTest): + + @classmethod + def setUpClass(cls): + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testSplittingAllArgs(self): + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{split_all_comma_separated_values: true, column_limit: 40}')) + unformatted_code = textwrap.dedent("""\ + responseDict = {"timestamp": timestamp, "someValue": value, "whatever": 120} + """) + expected_formatted_code = textwrap.dedent("""\ + responseDict = { + "timestamp": timestamp, + "someValue": value, + "whatever": 120 + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + yes = { 'yes': 'no', 'no': 'yes', } + """) + expected_formatted_code = textwrap.dedent("""\ + yes = { + 'yes': 'no', + 'no': 'yes', + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + unformatted_code = textwrap.dedent("""\ + def foo(long_arg, really_long_arg, really_really_long_arg, cant_keep_all_these_args): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(long_arg, + really_long_arg, + really_really_long_arg, + cant_keep_all_these_args): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + unformatted_code = textwrap.dedent("""\ + foo_tuple = [long_arg, really_long_arg, really_really_long_arg, cant_keep_all_these_args] + """) + expected_formatted_code = textwrap.dedent("""\ + foo_tuple = [ + long_arg, + really_long_arg, + really_really_long_arg, + cant_keep_all_these_args + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + unformatted_code = textwrap.dedent("""\ + foo_tuple = [short, arg] + """) + expected_formatted_code = textwrap.dedent("""\ + foo_tuple = [short, arg] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + # There is a test for split_all_top_level_comma_separated_values, with + # different expected value + unformatted_code = textwrap.dedent("""\ + someLongFunction(this_is_a_very_long_parameter, + abc=(a, this_will_just_fit_xxxxxxx)) + """) + expected_formatted_code = textwrap.dedent("""\ + someLongFunction( + this_is_a_very_long_parameter, + abc=(a, + this_will_just_fit_xxxxxxx)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSplittingTopLevelAllArgs(self): + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{split_all_top_level_comma_separated_values: true, column_limit: 40}' + )) + # Works the same way as split_all_comma_separated_values + unformatted_code = textwrap.dedent("""\ + responseDict = {"timestamp": timestamp, "someValue": value, "whatever": 120} + """) + expected_formatted_code = textwrap.dedent("""\ + responseDict = { + "timestamp": timestamp, + "someValue": value, + "whatever": 120 + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + # Works the same way as split_all_comma_separated_values + unformatted_code = textwrap.dedent("""\ + def foo(long_arg, really_long_arg, really_really_long_arg, cant_keep_all_these_args): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(long_arg, + really_long_arg, + really_really_long_arg, + cant_keep_all_these_args): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + # Works the same way as split_all_comma_separated_values + unformatted_code = textwrap.dedent("""\ + foo_tuple = [long_arg, really_long_arg, really_really_long_arg, cant_keep_all_these_args] + """) + expected_formatted_code = textwrap.dedent("""\ + foo_tuple = [ + long_arg, + really_long_arg, + really_really_long_arg, + cant_keep_all_these_args + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + # Works the same way as split_all_comma_separated_values + unformatted_code = textwrap.dedent("""\ + foo_tuple = [short, arg] + """) + expected_formatted_code = textwrap.dedent("""\ + foo_tuple = [short, arg] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + # There is a test for split_all_comma_separated_values, with different + # expected value + unformatted_code = textwrap.dedent("""\ + someLongFunction(this_is_a_very_long_parameter, + abc=(a, this_will_just_fit_xxxxxxx)) + """) + expected_formatted_code = textwrap.dedent("""\ + someLongFunction( + this_is_a_very_long_parameter, + abc=(a, this_will_just_fit_xxxxxxx)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + actual_formatted_code = reformatter.Reformat(uwlines) + self.assertEqual(40, len(actual_formatted_code.splitlines()[-1])) + self.assertCodeEqual(expected_formatted_code, actual_formatted_code) + + unformatted_code = textwrap.dedent("""\ + someLongFunction(this_is_a_very_long_parameter, + abc=(a, this_will_not_fit_xxxxxxxxx)) + """) + expected_formatted_code = textwrap.dedent("""\ + someLongFunction( + this_is_a_very_long_parameter, + abc=(a, + this_will_not_fit_xxxxxxxxx)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + # Exercise the case where there's no opening bracket (for a, b) + unformatted_code = textwrap.dedent("""\ + a, b = f( + a_very_long_parameter, yet_another_one, and_another) + """) + expected_formatted_code = textwrap.dedent("""\ + a, b = f( + a_very_long_parameter, yet_another_one, and_another) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + # Don't require splitting before comments. + unformatted_code = textwrap.dedent("""\ + KO = { + 'ABC': Abc, # abc + 'DEF': Def, # def + 'LOL': Lol, # wtf + 'GHI': Ghi, + 'JKL': Jkl, + } + """) + expected_formatted_code = textwrap.dedent("""\ + KO = { + 'ABC': Abc, # abc + 'DEF': Def, # def + 'LOL': Lol, # wtf + 'GHI': Ghi, + 'JKL': Jkl, + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSimpleFunctionsWithTrailingComments(self): + unformatted_code = textwrap.dedent("""\ + def g(): # Trailing comment + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + def f( # Intermediate comment + ): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def g(): # Trailing comment + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + + def f( # Intermediate comment + ): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testBlankLinesBetweenTopLevelImportsAndVariables(self): + unformatted_code = textwrap.dedent("""\ + import foo as bar + VAR = 'baz' + """) + expected_formatted_code = textwrap.dedent("""\ + import foo as bar + + VAR = 'baz' + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + import foo as bar + + VAR = 'baz' + """) + expected_formatted_code = textwrap.dedent("""\ + import foo as bar + + + VAR = 'baz' + """) + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: yapf, blank_lines_between_top_level_imports_and_variables: 2}' + )) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + unformatted_code = textwrap.dedent("""\ + import foo as bar + # Some comment + """) + expected_formatted_code = textwrap.dedent("""\ + import foo as bar + # Some comment + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + import foo as bar + class Baz(): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + import foo as bar + + + class Baz(): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + import foo as bar + def foobar(): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + import foo as bar + + + def foobar(): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + def foobar(): + from foo import Bar + Bar.baz() + """) + expected_formatted_code = textwrap.dedent("""\ + def foobar(): + from foo import Bar + Bar.baz() + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testBlankLinesAtEndOfFile(self): + unformatted_code = textwrap.dedent("""\ + def foobar(): # foo + pass + + + + """) + expected_formatted_code = textwrap.dedent("""\ + def foobar(): # foo + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + x = { 'a':37,'b':42, + + 'c':927} + + """) + expected_formatted_code = textwrap.dedent("""\ + x = {'a': 37, 'b': 42, 'c': 927} + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testIndentBlankLines(self): + unformatted_code = textwrap.dedent("""\ + class foo(object): + + def foobar(self): + + pass + + def barfoo(self, x, y): # bar + + if x: + + return y + + + def bar(): + + return 0 + """) + expected_formatted_code = """\ +class foo(object):\n \n def foobar(self):\n \n pass\n \n def barfoo(self, x, y): # bar\n \n if x:\n \n return y\n\n\ndef bar():\n \n return 0 +""" + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: yapf, indent_blank_lines: true}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + unformatted_code, expected_formatted_code = (expected_formatted_code, + unformatted_code) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testMultipleUgliness(self): + unformatted_code = textwrap.dedent("""\ + x = { 'a':37,'b':42, + + 'c':927} + + y = 'hello ''world' + z = 'hello '+'world' + a = 'hello {}'.format('world') + class foo ( object ): + def f (self ): + return 37*-+2 + def g(self, x,y=42): + return y + def f ( a ) : + return 37+-+a[42-x : y**3] + """) + expected_formatted_code = textwrap.dedent("""\ + x = {'a': 37, 'b': 42, 'c': 927} + + y = 'hello ' 'world' + z = 'hello ' + 'world' + a = 'hello {}'.format('world') + + + class foo(object): + + def f(self): + return 37 * -+2 + + def g(self, x, y=42): + return y + + + def f(a): + return 37 + -+a[42 - x:y**3] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testComments(self): + unformatted_code = textwrap.dedent("""\ + class Foo(object): + pass + + # Attached comment + class Bar(object): + pass + + global_assignment = 42 + + # Comment attached to class with decorator. + # Comment attached to class with decorator. + @noop + @noop + class Baz(object): + pass + + # Intermediate comment + + class Qux(object): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + class Foo(object): + pass + + + # Attached comment + class Bar(object): + pass + + + global_assignment = 42 + + + # Comment attached to class with decorator. + # Comment attached to class with decorator. + @noop + @noop + class Baz(object): + pass + + + # Intermediate comment + + + class Qux(object): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSingleComment(self): + code = textwrap.dedent("""\ + # Thing 1 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testCommentsWithTrailingSpaces(self): + unformatted_code = textwrap.dedent("""\ + # Thing 1 + # Thing 2 + """) + expected_formatted_code = textwrap.dedent("""\ + # Thing 1 + # Thing 2 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testCommentsInDataLiteral(self): + code = textwrap.dedent("""\ + def f(): + return collections.OrderedDict({ + # First comment. + 'fnord': 37, + + # Second comment. + # Continuation of second comment. + 'bork': 42, + + # Ending comment. + }) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testEndingWhitespaceAfterSimpleStatement(self): + code = textwrap.dedent("""\ + import foo as bar + # Thing 1 + # Thing 2 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testDocstrings(self): + unformatted_code = textwrap.dedent('''\ + u"""Module-level docstring.""" + import os + class Foo(object): + + """Class-level docstring.""" + # A comment for qux. + def qux(self): + + + """Function-level docstring. + + A multiline function docstring. + """ + print('hello {}'.format('world')) + return 42 + ''') + expected_formatted_code = textwrap.dedent('''\ + u"""Module-level docstring.""" + import os + + + class Foo(object): + """Class-level docstring.""" + + # A comment for qux. + def qux(self): + """Function-level docstring. + + A multiline function docstring. + """ + print('hello {}'.format('world')) + return 42 + ''') + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testDocstringAndMultilineComment(self): + unformatted_code = textwrap.dedent('''\ + """Hello world""" + # A multiline + # comment + class bar(object): + """class docstring""" + # class multiline + # comment + def foo(self): + """Another docstring.""" + # Another multiline + # comment + pass + ''') + expected_formatted_code = textwrap.dedent('''\ + """Hello world""" + + + # A multiline + # comment + class bar(object): + """class docstring""" + + # class multiline + # comment + def foo(self): + """Another docstring.""" + # Another multiline + # comment + pass + ''') + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testMultilineDocstringAndMultilineComment(self): + unformatted_code = textwrap.dedent('''\ + """Hello world + + RIP Dennis Richie. + """ + # A multiline + # comment + class bar(object): + """class docstring + + A classy class. + """ + # class multiline + # comment + def foo(self): + """Another docstring. + + A functional function. + """ + # Another multiline + # comment + pass + ''') + expected_formatted_code = textwrap.dedent('''\ + """Hello world + + RIP Dennis Richie. + """ + + + # A multiline + # comment + class bar(object): + """class docstring + + A classy class. + """ + + # class multiline + # comment + def foo(self): + """Another docstring. + + A functional function. + """ + # Another multiline + # comment + pass + ''') + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testTupleCommaBeforeLastParen(self): + unformatted_code = textwrap.dedent("""\ + a = ( 1, ) + """) + expected_formatted_code = textwrap.dedent("""\ + a = (1,) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testNoBreakOutsideOfBracket(self): + # FIXME(morbo): How this is formatted is not correct. But it's syntactically + # correct. + unformatted_code = textwrap.dedent("""\ + def f(): + assert port >= minimum, \ +'Unexpected port %d when minimum was %d.' % (port, minimum) + """) + expected_formatted_code = textwrap.dedent("""\ + def f(): + assert port >= minimum, 'Unexpected port %d when minimum was %d.' % (port, + minimum) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testBlankLinesBeforeDecorators(self): + unformatted_code = textwrap.dedent("""\ + @foo() + class A(object): + @bar() + @baz() + def x(self): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + @foo() + class A(object): + + @bar() + @baz() + def x(self): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testCommentBetweenDecorators(self): + unformatted_code = textwrap.dedent("""\ + @foo() + # frob + @bar + def x (self): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + @foo() + # frob + @bar + def x(self): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testListComprehension(self): + unformatted_code = textwrap.dedent("""\ + def given(y): + [k for k in () + if k in y] + """) + expected_formatted_code = textwrap.dedent("""\ + def given(y): + [k for k in () if k in y] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testListComprehensionPreferOneLine(self): + unformatted_code = textwrap.dedent("""\ + def given(y): + long_variable_name = [ + long_var_name + 1 + for long_var_name in () + if long_var_name == 2] + """) + expected_formatted_code = textwrap.dedent("""\ + def given(y): + long_variable_name = [ + long_var_name + 1 for long_var_name in () if long_var_name == 2 + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testListComprehensionPreferOneLineOverArithmeticSplit(self): + unformatted_code = textwrap.dedent("""\ + def given(used_identifiers): + return (sum(len(identifier) + for identifier in used_identifiers) / len(used_identifiers)) + """) + expected_formatted_code = textwrap.dedent("""\ + def given(used_identifiers): + return (sum(len(identifier) for identifier in used_identifiers) / + len(used_identifiers)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testListComprehensionPreferThreeLinesForLineWrap(self): + unformatted_code = textwrap.dedent("""\ + def given(y): + long_variable_name = [ + long_var_name + 1 + for long_var_name, number_two in () + if long_var_name == 2 and number_two == 3] + """) + expected_formatted_code = textwrap.dedent("""\ + def given(y): + long_variable_name = [ + long_var_name + 1 + for long_var_name, number_two in () + if long_var_name == 2 and number_two == 3 + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testListComprehensionPreferNoBreakForTrivialExpression(self): + unformatted_code = textwrap.dedent("""\ + def given(y): + long_variable_name = [ + long_var_name + for long_var_name, number_two in () + if long_var_name == 2 and number_two == 3] + """) + expected_formatted_code = textwrap.dedent("""\ + def given(y): + long_variable_name = [ + long_var_name for long_var_name, number_two in () + if long_var_name == 2 and number_two == 3 + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testOpeningAndClosingBrackets(self): + unformatted_code = """\ +foo( (1, ) ) +foo( ( 1, 2, 3 ) ) +foo( ( 1, 2, 3, ) ) +""" + expected_formatted_code = """\ +foo((1,)) +foo((1, 2, 3)) +foo(( + 1, + 2, + 3, +)) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSingleLineFunctions(self): + unformatted_code = textwrap.dedent("""\ + def foo(): return 42 + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): + return 42 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testNoQueueSeletionInMiddleOfLine(self): + # If the queue isn't properly constructed, then a token in the middle of the + # line may be selected as the one with least penalty. The tokens after that + # one are then splatted at the end of the line with no formatting. + unformatted_code = """\ +find_symbol(node.type) + "< " + " ".join(find_pattern(n) for n in node.child) + " >" +""" + expected_formatted_code = """\ +find_symbol(node.type) + "< " + " ".join( + find_pattern(n) for n in node.child) + " >" +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testNoSpacesBetweenSubscriptsAndCalls(self): + unformatted_code = textwrap.dedent("""\ + aaaaaaaaaa = bbbbbbbb.ccccccccc() [42] (a, 2) + """) + expected_formatted_code = textwrap.dedent("""\ + aaaaaaaaaa = bbbbbbbb.ccccccccc()[42](a, 2) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testNoSpacesBetweenOpeningBracketAndStartingOperator(self): + # Unary operator. + unformatted_code = textwrap.dedent("""\ + aaaaaaaaaa = bbbbbbbb.ccccccccc[ -1 ]( -42 ) + """) + expected_formatted_code = textwrap.dedent("""\ + aaaaaaaaaa = bbbbbbbb.ccccccccc[-1](-42) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + # Varargs and kwargs. + unformatted_code = textwrap.dedent("""\ + aaaaaaaaaa = bbbbbbbb.ccccccccc( *varargs ) + aaaaaaaaaa = bbbbbbbb.ccccccccc( **kwargs ) + """) + expected_formatted_code = textwrap.dedent("""\ + aaaaaaaaaa = bbbbbbbb.ccccccccc(*varargs) + aaaaaaaaaa = bbbbbbbb.ccccccccc(**kwargs) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testMultilineCommentReformatted(self): + unformatted_code = textwrap.dedent("""\ + if True: + # This is a multiline + # comment. + pass + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + # This is a multiline + # comment. + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testDictionaryMakerFormatting(self): + unformatted_code = textwrap.dedent("""\ + _PYTHON_STATEMENTS = frozenset({ + lambda x, y: 'simple_stmt': 'small_stmt', 'expr_stmt': 'print_stmt', 'del_stmt': + 'pass_stmt', lambda: 'break_stmt': 'continue_stmt', 'return_stmt': 'raise_stmt', + 'yield_stmt': 'import_stmt', lambda: 'global_stmt': 'exec_stmt', 'assert_stmt': + 'if_stmt', 'while_stmt': 'for_stmt', + }) + """) + expected_formatted_code = textwrap.dedent("""\ + _PYTHON_STATEMENTS = frozenset({ + lambda x, y: 'simple_stmt': 'small_stmt', + 'expr_stmt': 'print_stmt', + 'del_stmt': 'pass_stmt', + lambda: 'break_stmt': 'continue_stmt', + 'return_stmt': 'raise_stmt', + 'yield_stmt': 'import_stmt', + lambda: 'global_stmt': 'exec_stmt', + 'assert_stmt': 'if_stmt', + 'while_stmt': 'for_stmt', + }) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSimpleMultilineCode(self): + unformatted_code = textwrap.dedent("""\ + if True: + aaaaaaaaaaaaaa.bbbbbbbbbbbbbb.ccccccc(zzzzzzzzzzzz, \ +xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv) + aaaaaaaaaaaaaa.bbbbbbbbbbbbbb.ccccccc(zzzzzzzzzzzz, \ +xxxxxxxxxxx, yyyyyyyyyyyy, vvvvvvvvv) + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + aaaaaaaaaaaaaa.bbbbbbbbbbbbbb.ccccccc(zzzzzzzzzzzz, xxxxxxxxxxx, yyyyyyyyyyyy, + vvvvvvvvv) + aaaaaaaaaaaaaa.bbbbbbbbbbbbbb.ccccccc(zzzzzzzzzzzz, xxxxxxxxxxx, yyyyyyyyyyyy, + vvvvvvvvv) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testMultilineComment(self): + code = textwrap.dedent("""\ + if Foo: + # Hello world + # Yo man. + # Yo man. + # Yo man. + # Yo man. + a = 42 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testSpaceBetweenStringAndParentheses(self): + code = textwrap.dedent("""\ + b = '0' ('hello') + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testMultilineString(self): + code = textwrap.dedent("""\ + code = textwrap.dedent('''\ + if Foo: + # Hello world + # Yo man. + # Yo man. + # Yo man. + # Yo man. + a = 42 + ''') + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent('''\ + def f(): + email_text += """This is a really long docstring that goes over the column limit and is multi-line.

+ Czar: """+despot["Nicholas"]+"""
+ Minion: """+serf["Dmitri"]+"""
+ Residence: """+palace["Winter"]+"""
+ + """ + ''') + expected_formatted_code = textwrap.dedent('''\ + def f(): + email_text += """This is a really long docstring that goes over the column limit and is multi-line.

+ Czar: """ + despot["Nicholas"] + """
+ Minion: """ + serf["Dmitri"] + """
+ Residence: """ + palace["Winter"] + """
+ + """ + ''') + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSimpleMultilineWithComments(self): + code = textwrap.dedent("""\ + if ( # This is the first comment + a and # This is the second comment + # This is the third comment + b): # A trailing comment + # Whoa! A normal comment!! + pass # Another trailing comment + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testMatchingParenSplittingMatching(self): + unformatted_code = textwrap.dedent("""\ + def f(): + raise RuntimeError('unable to find insertion point for target node', + (target,)) + """) + expected_formatted_code = textwrap.dedent("""\ + def f(): + raise RuntimeError('unable to find insertion point for target node', + (target,)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testContinuationIndent(self): + unformatted_code = textwrap.dedent('''\ + class F: + def _ProcessArgLists(self, node): + """Common method for processing argument lists.""" + for child in node.children: + if isinstance(child, pytree.Leaf): + self._SetTokenSubtype( + child, subtype=_ARGLIST_TOKEN_TO_SUBTYPE.get( + child.value, format_token.Subtype.NONE)) + ''') + expected_formatted_code = textwrap.dedent('''\ + class F: + + def _ProcessArgLists(self, node): + """Common method for processing argument lists.""" + for child in node.children: + if isinstance(child, pytree.Leaf): + self._SetTokenSubtype( + child, + subtype=_ARGLIST_TOKEN_TO_SUBTYPE.get(child.value, + format_token.Subtype.NONE)) + ''') + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testTrailingCommaAndBracket(self): + unformatted_code = textwrap.dedent('''\ + a = { 42, } + b = ( 42, ) + c = [ 42, ] + ''') + expected_formatted_code = textwrap.dedent('''\ + a = { + 42, + } + b = (42,) + c = [ + 42, + ] + ''') + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testI18n(self): + code = textwrap.dedent("""\ + N_('Some years ago - never mind how long precisely - having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world.') # A comment is here. + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + code = textwrap.dedent("""\ + foo('Fake function call') #. Some years ago - never mind how long precisely - having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testI18nCommentsInDataLiteral(self): + code = textwrap.dedent("""\ + def f(): + return collections.OrderedDict({ + #. First i18n comment. + 'bork': 'foo', + + #. Second i18n comment. + 'snork': 'bar#.*=\\\\0', + }) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testClosingBracketIndent(self): + code = textwrap.dedent('''\ + def f(): + + def g(): + while (xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxxxxxxxxxxx( + yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) == 'bbbbbbb'): + pass + ''') + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testClosingBracketsInlinedInCall(self): + unformatted_code = textwrap.dedent("""\ + class Foo(object): + + def bar(self): + self.aaaaaaaa = xxxxxxxxxxxxxxxxxxx.yyyyyyyyyyyyy( + self.cccccc.ddddddddd.eeeeeeee, + options={ + "forkforkfork": 1, + "borkborkbork": 2, + "corkcorkcork": 3, + "horkhorkhork": 4, + "porkporkpork": 5, + }) + """) + expected_formatted_code = textwrap.dedent("""\ + class Foo(object): + + def bar(self): + self.aaaaaaaa = xxxxxxxxxxxxxxxxxxx.yyyyyyyyyyyyy( + self.cccccc.ddddddddd.eeeeeeee, + options={ + "forkforkfork": 1, + "borkborkbork": 2, + "corkcorkcork": 3, + "horkhorkhork": 4, + "porkporkpork": 5, + }) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testLineWrapInForExpression(self): + code = textwrap.dedent("""\ + class A: + + def x(self, node, name, n=1): + for i, child in enumerate( + itertools.ifilter(lambda c: pytree_utils.NodeName(c) == name, + node.pre_order())): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testFunctionCallContinuationLine(self): + code = """\ +class foo: + + def bar(self, node, name, n=1): + if True: + if True: + return [(aaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb( + cccc, ddddddddddddddddddddddddddddddddddddd))] +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testI18nNonFormatting(self): + code = textwrap.dedent("""\ + class F(object): + + def __init__(self, fieldname, + #. Error message indicating an invalid e-mail address. + message=N_('Please check your email address.'), **kwargs): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testNoSpaceBetweenUnaryOpAndOpeningParen(self): + code = textwrap.dedent("""\ + if ~(a or b): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testCommentBeforeFuncDef(self): + code = textwrap.dedent("""\ + class Foo(object): + + a = 42 + + # This is a comment. + def __init__(self, + xxxxxxx, + yyyyy=0, + zzzzzzz=None, + aaaaaaaaaaaaaaaaaa=False, + bbbbbbbbbbbbbbb=False): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testExcessLineCountWithDefaultKeywords(self): + unformatted_code = textwrap.dedent("""\ + class Fnord(object): + def Moo(self): + aaaaaaaaaaaaaaaa = self._bbbbbbbbbbbbbbbbbbbbbbb( + ccccccccccccc=ccccccccccccc, ddddddd=ddddddd, eeee=eeee, + fffff=fffff, ggggggg=ggggggg, hhhhhhhhhhhhh=hhhhhhhhhhhhh, + iiiiiii=iiiiiiiiiiiiii) + """) + expected_formatted_code = textwrap.dedent("""\ + class Fnord(object): + + def Moo(self): + aaaaaaaaaaaaaaaa = self._bbbbbbbbbbbbbbbbbbbbbbb( + ccccccccccccc=ccccccccccccc, + ddddddd=ddddddd, + eeee=eeee, + fffff=fffff, + ggggggg=ggggggg, + hhhhhhhhhhhhh=hhhhhhhhhhhhh, + iiiiiii=iiiiiiiiiiiiii) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSpaceAfterNotOperator(self): + code = textwrap.dedent("""\ + if not (this and that): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testNoPenaltySplitting(self): + code = textwrap.dedent("""\ + def f(): + if True: + if True: + python_files.extend( + os.path.join(filename, f) + for f in os.listdir(filename) + if IsPythonFile(os.path.join(filename, f))) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testExpressionPenalties(self): + code = textwrap.dedent("""\ + def f(): + if ((left.value == '(' and right.value == ')') or + (left.value == '[' and right.value == ']') or + (left.value == '{' and right.value == '}')): + return False + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testLineDepthOfSingleLineStatement(self): + unformatted_code = textwrap.dedent("""\ + while True: continue + for x in range(3): continue + try: a = 42 + except: b = 42 + with open(a) as fd: a = fd.read() + """) + expected_formatted_code = textwrap.dedent("""\ + while True: + continue + for x in range(3): + continue + try: + a = 42 + except: + b = 42 + with open(a) as fd: + a = fd.read() + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSplitListWithTerminatingComma(self): + unformatted_code = textwrap.dedent("""\ + FOO = ['bar', 'baz', 'mux', 'qux', 'quux', 'quuux', 'quuuux', + 'quuuuux', 'quuuuuux', 'quuuuuuux', lambda a, b: 37,] + """) + expected_formatted_code = textwrap.dedent("""\ + FOO = [ + 'bar', + 'baz', + 'mux', + 'qux', + 'quux', + 'quuux', + 'quuuux', + 'quuuuux', + 'quuuuuux', + 'quuuuuuux', + lambda a, b: 37, + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSplitListWithInterspersedComments(self): + code = textwrap.dedent("""\ + FOO = [ + 'bar', # bar + 'baz', # baz + 'mux', # mux + 'qux', # qux + 'quux', # quux + 'quuux', # quuux + 'quuuux', # quuuux + 'quuuuux', # quuuuux + 'quuuuuux', # quuuuuux + 'quuuuuuux', # quuuuuuux + lambda a, b: 37 # lambda + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testRelativeImportStatements(self): + code = textwrap.dedent("""\ + from ... import bork + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testSingleLineList(self): + # A list on a single line should prefer to remain contiguous. + unformatted_code = textwrap.dedent("""\ + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = aaaaaaaaaaa( + ("...", "."), "..", + ".............................................." + ) + """) + expected_formatted_code = textwrap.dedent("""\ + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb = aaaaaaaaaaa( + ("...", "."), "..", "..............................................") + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testBlankLinesBeforeFunctionsNotInColumnZero(self): + unformatted_code = textwrap.dedent("""\ + import signal + + + try: + signal.SIGALRM + # .................................................................. + # ............................................................... + + + def timeout(seconds=1): + pass + except: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + import signal + + try: + signal.SIGALRM + + # .................................................................. + # ............................................................... + + + def timeout(seconds=1): + pass + except: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testNoKeywordArgumentBreakage(self): + code = textwrap.dedent("""\ + class A(object): + + def b(self): + if self.aaaaaaaaaaaaaaaaaaaa not in self.bbbbbbbbbb( + cccccccccccccccccccc=True): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testTrailerOnSingleLine(self): + code = """\ +urlpatterns = patterns('', url(r'^$', 'homepage_view'), + url(r'^/login/$', 'login_view'), + url(r'^/login/$', 'logout_view'), + url(r'^/user/(?P\\w+)/$', 'profile_view')) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testIfConditionalParens(self): + code = textwrap.dedent("""\ + class Foo: + + def bar(): + if True: + if (child.type == grammar_token.NAME and + child.value in substatement_names): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testContinuationMarkers(self): + code = textwrap.dedent("""\ + text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. "\\ + "Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur "\\ + "ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis "\\ + "sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. "\\ + "Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet" + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + code = textwrap.dedent("""\ + from __future__ import nested_scopes, generators, division, absolute_import, with_statement, \\ + print_function, unicode_literals + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + code = textwrap.dedent("""\ + if aaaaaaaaa == 42 and bbbbbbbbbbbbbb == 42 and \\ + cccccccc == 42: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testCommentsWithContinuationMarkers(self): + code = textwrap.dedent("""\ + def fn(arg): + v = fn2(key1=True, + #c1 + key2=arg)\\ + .fn3() + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testMultipleContinuationMarkers(self): + code = textwrap.dedent("""\ + xyz = \\ + \\ + some_thing() + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testContinuationMarkerAfterStringWithContinuation(self): + code = """\ +s = 'foo \\ + bar' \\ + .format() +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testEmptyContainers(self): + code = textwrap.dedent("""\ + flags.DEFINE_list( + 'output_dirs', [], + 'Lorem ipsum dolor sit amet, consetetur adipiscing elit. Donec a diam lectus. ' + 'Sed sit amet ipsum mauris. Maecenas congue.') + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testSplitStringsIfSurroundedByParens(self): + unformatted_code = textwrap.dedent("""\ + a = foo.bar({'xxxxxxxxxxxxxxxxxxxxxxx' 'yyyyyyyyyyyyyyyyyyyyyyyyyy': baz[42]} + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbb' 'cccccccccccccccccccccccccccccccc' 'ddddddddddddddddddddddddddddd') + """) + expected_formatted_code = textwrap.dedent("""\ + a = foo.bar({'xxxxxxxxxxxxxxxxxxxxxxx' + 'yyyyyyyyyyyyyyyyyyyyyyyyyy': baz[42]} + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + 'bbbbbbbbbbbbbbbbbbbbbbbbbb' + 'cccccccccccccccccccccccccccccccc' + 'ddddddddddddddddddddddddddddd') + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + code = textwrap.dedent("""\ + a = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' \ +'bbbbbbbbbbbbbbbbbbbbbbbbbb' 'cccccccccccccccccccccccccccccccc' \ +'ddddddddddddddddddddddddddddd' + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testMultilineShebang(self): + code = textwrap.dedent("""\ + #!/bin/sh + if "true" : '''\' + then + + export FOO=123 + exec /usr/bin/env python "$0" "$@" + + exit 127 + fi + ''' + + import os + + assert os.environ['FOO'] == '123' + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testNoSplittingAroundTermOperators(self): + code = textwrap.dedent("""\ + a_very_long_function_call_yada_yada_etc_etc_etc(long_arg1, + long_arg2 / long_arg3) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testNoSplittingWithinSubscriptList(self): + code = textwrap.dedent("""\ + somequitelongvariablename.somemember[(a, b)] = { + 'somelongkey': 1, + 'someotherlongkey': 2 + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testExcessCharacters(self): + code = textwrap.dedent("""\ + class foo: + + def bar(self): + self.write(s=[ + '%s%s %s' % ('many of really', 'long strings', '+ just makes up 81') + ]) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + def _(): + if True: + if True: + if contract == allow_contract and attr_dict.get(if_attribute) == has_value: + return True + """) + expected_code = textwrap.dedent("""\ + def _(): + if True: + if True: + if contract == allow_contract and attr_dict.get( + if_attribute) == has_value: + return True + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_code, reformatter.Reformat(uwlines)) + + def testDictSetGenerator(self): + code = textwrap.dedent("""\ + foo = { + variable: 'hello world. How are you today?' + for variable in fnord + if variable != 37 + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testUnaryOpInDictionaryValue(self): + code = textwrap.dedent("""\ + beta = "123" + + test = {'alpha': beta[-1]} + + print(beta[-1]) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testUnaryNotOperator(self): + code = textwrap.dedent("""\ + if True: + if True: + if True: + if True: + remote_checksum = self.get_checksum(conn, tmp, dest, inject, + not directory_prepended, source) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testRelaxArraySubscriptAffinity(self): + code = """\ +class A(object): + + def f(self, aaaaaaaaa, bbbbbbbbbbbbb, row): + if True: + if True: + if True: + if True: + if row[4] is None or row[5] is None: + bbbbbbbbbbbbb[ + '..............'] = row[5] if row[5] is not None else 5 +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testFunctionCallInDict(self): + code = "a = {'a': b(c=d, **e)}\n" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testFunctionCallInNestedDict(self): + code = "a = {'a': {'a': {'a': b(c=d, **e)}}}\n" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testUnbreakableNot(self): + code = textwrap.dedent("""\ + def test(): + if not "Foooooooooooooooooooooooooooooo" or "Foooooooooooooooooooooooooooooo" == "Foooooooooooooooooooooooooooooo": + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testSplitListWithComment(self): + code = textwrap.dedent("""\ + a = [ + 'a', + 'b', + 'c' # hello world + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testOverColumnLimit(self): + unformatted_code = textwrap.dedent("""\ + class Test: + + def testSomething(self): + expected = { + ('aaaaaaaaaaaaa', 'bbbb'): 'ccccccccccccccccccccccccccccccccccccccccccc', + ('aaaaaaaaaaaaa', 'bbbb'): 'ccccccccccccccccccccccccccccccccccccccccccc', + ('aaaaaaaaaaaaa', 'bbbb'): 'ccccccccccccccccccccccccccccccccccccccccccc', + } + """) + expected_formatted_code = textwrap.dedent("""\ + class Test: + + def testSomething(self): + expected = { + ('aaaaaaaaaaaaa', 'bbbb'): + 'ccccccccccccccccccccccccccccccccccccccccccc', + ('aaaaaaaaaaaaa', 'bbbb'): + 'ccccccccccccccccccccccccccccccccccccccccccc', + ('aaaaaaaaaaaaa', 'bbbb'): + 'ccccccccccccccccccccccccccccccccccccccccccc', + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testEndingComment(self): + code = textwrap.dedent("""\ + a = f( + a="something", + b="something requiring comment which is quite long", # comment about b (pushes line over 79) + c="something else, about which comment doesn't make sense") + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testContinuationSpaceRetention(self): + code = textwrap.dedent("""\ + def fn(): + return module \\ + .method(Object(data, + fn2(arg) + )) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testIfExpressionWithFunctionCall(self): + code = textwrap.dedent("""\ + if x or z.y( + a, + c, + aaaaaaaaaaaaaaaaaaaaa=aaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbb=bbbbbbbbbbbbbbbbbb): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testUnformattedAfterMultilineString(self): + code = textwrap.dedent("""\ + def foo(): + com_text = \\ + ''' + TEST + ''' % (input_fname, output_fname) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testNoSpacesAroundKeywordDefaultValues(self): + code = textwrap.dedent("""\ + sources = { + 'json': request.get_json(silent=True) or {}, + 'json2': request.get_json(silent=True), + } + json = request.get_json(silent=True) or {} + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testNoSplittingBeforeEndingSubscriptBracket(self): + unformatted_code = textwrap.dedent("""\ + if True: + if True: + status = cf.describe_stacks(StackName=stackname)[u'Stacks'][0][u'StackStatus'] + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + if True: + status = cf.describe_stacks( + StackName=stackname)[u'Stacks'][0][u'StackStatus'] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testNoSplittingOnSingleArgument(self): + unformatted_code = textwrap.dedent("""\ + xxxxxxxxxxxxxx = (re.search(r'(\\d+\\.\\d+\\.\\d+\\.)\\d+', + aaaaaaa.bbbbbbbbbbbb).group(1) + + re.search(r'\\d+\\.\\d+\\.\\d+\\.(\\d+)', + ccccccc).group(1)) + xxxxxxxxxxxxxx = (re.search(r'(\\d+\\.\\d+\\.\\d+\\.)\\d+', + aaaaaaa.bbbbbbbbbbbb).group(a.b) + + re.search(r'\\d+\\.\\d+\\.\\d+\\.(\\d+)', + ccccccc).group(c.d)) + """) + expected_formatted_code = textwrap.dedent("""\ + xxxxxxxxxxxxxx = ( + re.search(r'(\\d+\\.\\d+\\.\\d+\\.)\\d+', aaaaaaa.bbbbbbbbbbbb).group(1) + + re.search(r'\\d+\\.\\d+\\.\\d+\\.(\\d+)', ccccccc).group(1)) + xxxxxxxxxxxxxx = ( + re.search(r'(\\d+\\.\\d+\\.\\d+\\.)\\d+', aaaaaaa.bbbbbbbbbbbb).group(a.b) + + re.search(r'\\d+\\.\\d+\\.\\d+\\.(\\d+)', ccccccc).group(c.d)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSplittingArraysSensibly(self): + unformatted_code = textwrap.dedent("""\ + while True: + while True: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = list['bbbbbbbbbbbbbbbbbbbbbbbbb'].split(',') + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = list('bbbbbbbbbbbbbbbbbbbbbbbbb').split(',') + """) + expected_formatted_code = textwrap.dedent("""\ + while True: + while True: + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = list[ + 'bbbbbbbbbbbbbbbbbbbbbbbbb'].split(',') + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = list( + 'bbbbbbbbbbbbbbbbbbbbbbbbb').split(',') + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testComprehensionForAndIf(self): + unformatted_code = textwrap.dedent("""\ + class f: + + def __repr__(self): + tokens_repr = ','.join(['{0}({1!r})'.format(tok.name, tok.value) for tok in self._tokens]) + """) + expected_formatted_code = textwrap.dedent("""\ + class f: + + def __repr__(self): + tokens_repr = ','.join( + ['{0}({1!r})'.format(tok.name, tok.value) for tok in self._tokens]) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testFunctionCallArguments(self): + unformatted_code = textwrap.dedent("""\ + def f(): + if True: + pytree_utils.InsertNodesBefore(_CreateCommentsFromPrefix( + comment_prefix, comment_lineno, comment_column, + standalone=True), ancestor_at_indent) + pytree_utils.InsertNodesBefore(_CreateCommentsFromPrefix( + comment_prefix, comment_lineno, comment_column, + standalone=True)) + """) + expected_formatted_code = textwrap.dedent("""\ + def f(): + if True: + pytree_utils.InsertNodesBefore( + _CreateCommentsFromPrefix( + comment_prefix, comment_lineno, comment_column, standalone=True), + ancestor_at_indent) + pytree_utils.InsertNodesBefore( + _CreateCommentsFromPrefix( + comment_prefix, comment_lineno, comment_column, standalone=True)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testBinaryOperators(self): + unformatted_code = textwrap.dedent("""\ + a = b ** 37 + c = (20 ** -3) / (_GRID_ROWS ** (code_length - 10)) + """) + expected_formatted_code = textwrap.dedent("""\ + a = b**37 + c = (20**-3) / (_GRID_ROWS**(code_length - 10)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + code = textwrap.dedent("""\ + def f(): + if True: + if (self.stack[-1].split_before_closing_bracket and + # FIXME(morbo): Use the 'matching_bracket' instead of this. + # FIXME(morbo): Don't forget about tuples! + current.value in ']}'): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testContiguousList(self): + code = textwrap.dedent("""\ + [retval1, retval2] = a_very_long_function(argument_1, argument2, argument_3, + argument_4) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testArgsAndKwargsFormatting(self): + code = textwrap.dedent("""\ + a(a=aaaaaaaaaaaaaaaaaaaaa, + b=aaaaaaaaaaaaaaaaaaaaaaaa, + c=aaaaaaaaaaaaaaaaaa, + *d, + **e) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + code = textwrap.dedent("""\ + def foo(): + return [ + Bar(xxx='some string', + yyy='another long string', + zzz='a third long string') + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testCommentColumnLimitOverflow(self): + code = textwrap.dedent("""\ + def f(): + if True: + TaskManager.get_tags = MagicMock( + name='get_tags_mock', + return_value=[157031694470475], + # side_effect=[(157031694470475), (157031694470475),], + ) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testMultilineLambdas(self): + unformatted_code = textwrap.dedent("""\ + class SomeClass(object): + do_something = True + + def succeeded(self, dddddddddddddd): + d = defer.succeed(None) + + if self.do_something: + d.addCallback(lambda _: self.aaaaaa.bbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccccccc(dddddddddddddd)) + return d + """) + expected_formatted_code = textwrap.dedent("""\ + class SomeClass(object): + do_something = True + + def succeeded(self, dddddddddddddd): + d = defer.succeed(None) + + if self.do_something: + d.addCallback(lambda _: self.aaaaaa.bbbbbbbbbbbbbbbb. + cccccccccccccccccccccccccccccccc(dddddddddddddd)) + return d + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: yapf, allow_multiline_lambdas: true}')) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testMultilineDictionaryKeys(self): + unformatted_code = textwrap.dedent("""\ + MAP_WITH_LONG_KEYS = { + ('lorem ipsum', 'dolor sit amet'): + 1, + ('consectetur adipiscing elit.', 'Vestibulum mauris justo, ornare eget dolor eget'): + 2, + ('vehicula convallis nulla. Vestibulum dictum nisl in malesuada finibus.',): + 3 + } + """) + expected_formatted_code = textwrap.dedent("""\ + MAP_WITH_LONG_KEYS = { + ('lorem ipsum', 'dolor sit amet'): + 1, + ('consectetur adipiscing elit.', + 'Vestibulum mauris justo, ornare eget dolor eget'): + 2, + ('vehicula convallis nulla. Vestibulum dictum nisl in malesuada finibus.',): + 3 + } + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig('{based_on_style: yapf, ' + 'allow_multiline_dictionary_keys: true}')) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testStableDictionaryFormatting(self): + code = textwrap.dedent("""\ + class A(object): + def method(self): + filters = { + 'expressions': [{ + 'field': { + 'search_field': { + 'user_field': 'latest_party__number_of_guests' + }, + } + }] + } + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: pep8, indent_width: 2, ' + 'continuation_indent_width: 4, indent_dictionary_value: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(code) + reformatted_code = reformatter.Reformat(uwlines) + self.assertCodeEqual(code, reformatted_code) + + uwlines = yapf_test_helper.ParseAndUnwrap(reformatted_code) + reformatted_code = reformatter.Reformat(uwlines) + self.assertCodeEqual(code, reformatted_code) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testStableInlinedDictionaryFormatting(self): + try: + style.SetGlobalStyle(style.CreatePEP8Style()) + unformatted_code = textwrap.dedent("""\ + def _(): + url = "http://{0}/axis-cgi/admin/param.cgi?{1}".format( + value, urllib.urlencode({'action': 'update', 'parameter': value})) + """) + expected_formatted_code = textwrap.dedent("""\ + def _(): + url = "http://{0}/axis-cgi/admin/param.cgi?{1}".format( + value, urllib.urlencode({ + 'action': 'update', + 'parameter': value + })) + """) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + reformatted_code = reformatter.Reformat(uwlines) + self.assertCodeEqual(expected_formatted_code, reformatted_code) + + uwlines = yapf_test_helper.ParseAndUnwrap(reformatted_code) + reformatted_code = reformatter.Reformat(uwlines) + self.assertCodeEqual(expected_formatted_code, reformatted_code) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testDontSplitKeywordValueArguments(self): + unformatted_code = textwrap.dedent("""\ + def mark_game_scored(gid): + _connect.execute(_games.update().where(_games.c.gid == gid).values( + scored=True)) + """) + expected_formatted_code = textwrap.dedent("""\ + def mark_game_scored(gid): + _connect.execute( + _games.update().where(_games.c.gid == gid).values(scored=True)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testDontAddBlankLineAfterMultilineString(self): + code = textwrap.dedent("""\ + query = '''SELECT id + FROM table + WHERE day in {}''' + days = ",".join(days) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testFormattingListComprehensions(self): + code = textwrap.dedent("""\ + def a(): + if True: + if True: + if True: + columns = [ + x for x, y in self._heap_this_is_very_long if x.route[0] == choice + ] + self._heap = [x for x in self._heap if x.route and x.route[0] == choice] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testNoSplittingWhenBinPacking(self): + code = textwrap.dedent("""\ + a_very_long_function_name( + long_argument_name_1=1, + long_argument_name_2=2, + long_argument_name_3=3, + long_argument_name_4=4, + ) + + a_very_long_function_name( + long_argument_name_1=1, long_argument_name_2=2, long_argument_name_3=3, + long_argument_name_4=4 + ) + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: pep8, indent_width: 2, ' + 'continuation_indent_width: 4, indent_dictionary_value: True, ' + 'dedent_closing_brackets: True, ' + 'split_before_named_assigns: False}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(code) + reformatted_code = reformatter.Reformat(uwlines) + self.assertCodeEqual(code, reformatted_code) + + uwlines = yapf_test_helper.ParseAndUnwrap(reformatted_code) + reformatted_code = reformatter.Reformat(uwlines) + self.assertCodeEqual(code, reformatted_code) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testNotSplittingAfterSubscript(self): + unformatted_code = textwrap.dedent("""\ + if not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b(c == d[ + 'eeeeee']).ffffff(): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + if not aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b( + c == d['eeeeee']).ffffff(): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSplittingOneArgumentList(self): + unformatted_code = textwrap.dedent("""\ + def _(): + if True: + if True: + if True: + if True: + if True: + boxes[id_] = np.concatenate((points.min(axis=0), qoints.max(axis=0))) + """) + expected_formatted_code = textwrap.dedent("""\ + def _(): + if True: + if True: + if True: + if True: + if True: + boxes[id_] = np.concatenate( + (points.min(axis=0), qoints.max(axis=0))) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSplittingBeforeFirstElementListArgument(self): + unformatted_code = textwrap.dedent("""\ + class _(): + @classmethod + def _pack_results_for_constraint_or(cls, combination, constraints): + if True: + if True: + if True: + return cls._create_investigation_result( + ( + clue for clue in combination if not clue == Verifier.UNMATCHED + ), constraints, InvestigationResult.OR + ) + """) + expected_formatted_code = textwrap.dedent("""\ + class _(): + + @classmethod + def _pack_results_for_constraint_or(cls, combination, constraints): + if True: + if True: + if True: + return cls._create_investigation_result( + (clue for clue in combination if not clue == Verifier.UNMATCHED), + constraints, InvestigationResult.OR) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSplittingArgumentsTerminatedByComma(self): + unformatted_code = textwrap.dedent("""\ + function_name(argument_name_1=1, argument_name_2=2, argument_name_3=3) + + function_name(argument_name_1=1, argument_name_2=2, argument_name_3=3,) + + a_very_long_function_name(long_argument_name_1=1, long_argument_name_2=2, long_argument_name_3=3, long_argument_name_4=4) + + a_very_long_function_name(long_argument_name_1, long_argument_name_2, long_argument_name_3, long_argument_name_4,) + + r =f0 (1, 2,3,) + """) + expected_formatted_code = textwrap.dedent("""\ + function_name(argument_name_1=1, argument_name_2=2, argument_name_3=3) + + function_name( + argument_name_1=1, + argument_name_2=2, + argument_name_3=3, + ) + + a_very_long_function_name( + long_argument_name_1=1, + long_argument_name_2=2, + long_argument_name_3=3, + long_argument_name_4=4) + + a_very_long_function_name( + long_argument_name_1, + long_argument_name_2, + long_argument_name_3, + long_argument_name_4, + ) + + r = f0( + 1, + 2, + 3, + ) + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: yapf, ' + 'split_arguments_when_comma_terminated: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + reformatted_code = reformatter.Reformat(uwlines) + self.assertCodeEqual(expected_formatted_code, reformatted_code) + + uwlines = yapf_test_helper.ParseAndUnwrap(reformatted_code) + reformatted_code = reformatter.Reformat(uwlines) + self.assertCodeEqual(expected_formatted_code, reformatted_code) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testImportAsList(self): + code = textwrap.dedent("""\ + from toto import titi, tata, tutu # noqa + from toto import titi, tata, tutu + from toto import (titi, tata, tutu) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testDictionaryValuesOnOwnLines(self): + unformatted_code = textwrap.dedent("""\ + a = { + 'aaaaaaaaaaaaaaaaaaaaaaaa': + Check('ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ', '=', True), + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb': + Check('YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY', '=', True), + 'ccccccccccccccc': + Check('XXXXXXXXXXXXXXXXXXX', '!=', 'SUSPENDED'), + 'dddddddddddddddddddddddddddddd': + Check('WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW', '=', False), + 'eeeeeeeeeeeeeeeeeeeeeeeeeeeee': + Check('VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV', '=', False), + 'ffffffffffffffffffffffffff': + Check('UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU', '=', True), + 'ggggggggggggggggg': + Check('TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT', '=', True), + 'hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh': + Check('SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS', '=', True), + 'iiiiiiiiiiiiiiiiiiiiiiii': + Check('RRRRRRRRRRRRRRRRRRRRRRRRRRR', '=', True), + 'jjjjjjjjjjjjjjjjjjjjjjjjjj': + Check('QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ', '=', False), + } + """) + expected_formatted_code = textwrap.dedent("""\ + a = { + 'aaaaaaaaaaaaaaaaaaaaaaaa': + Check('ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ', '=', True), + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb': + Check('YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY', '=', True), + 'ccccccccccccccc': + Check('XXXXXXXXXXXXXXXXXXX', '!=', 'SUSPENDED'), + 'dddddddddddddddddddddddddddddd': + Check('WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW', '=', False), + 'eeeeeeeeeeeeeeeeeeeeeeeeeeeee': + Check('VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV', '=', False), + 'ffffffffffffffffffffffffff': + Check('UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU', '=', True), + 'ggggggggggggggggg': + Check('TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT', '=', True), + 'hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh': + Check('SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS', '=', True), + 'iiiiiiiiiiiiiiiiiiiiiiii': + Check('RRRRRRRRRRRRRRRRRRRRRRRRRRR', '=', True), + 'jjjjjjjjjjjjjjjjjjjjjjjjjj': + Check('QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ', '=', False), + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testDictionaryOnOwnLine(self): + unformatted_code = textwrap.dedent("""\ + doc = test_utils.CreateTestDocumentViaController( + content={ 'a': 'b' }, + branch_key=branch.key, + collection_key=collection.key) + """) + expected_formatted_code = textwrap.dedent("""\ + doc = test_utils.CreateTestDocumentViaController( + content={'a': 'b'}, branch_key=branch.key, collection_key=collection.key) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + doc = test_utils.CreateTestDocumentViaController( + content={ 'a': 'b' }, + branch_key=branch.key, + collection_key=collection.key, + collection_key2=collection.key2) + """) + expected_formatted_code = textwrap.dedent("""\ + doc = test_utils.CreateTestDocumentViaController( + content={'a': 'b'}, + branch_key=branch.key, + collection_key=collection.key, + collection_key2=collection.key2) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testNestedListsInDictionary(self): + unformatted_code = textwrap.dedent("""\ + _A = { + 'cccccccccc': ('^^1',), + 'rrrrrrrrrrrrrrrrrrrrrrrrr': ('^7913', # AAAAAAAAAAAAAA. + ), + 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee': ('^6242', # BBBBBBBBBBBBBBB. + ), + 'vvvvvvvvvvvvvvvvvvv': ('^27959', # CCCCCCCCCCCCCCCCCC. + '^19746', # DDDDDDDDDDDDDDDDDDDDDDD. + '^22907', # EEEEEEEEEEEEEEEEEEEEEEEE. + '^21098', # FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF. + '^22826', # GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG. + '^22769', # HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH. + '^22935', # IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII. + '^3982', # JJJJJJJJJJJJJ. + ), + 'uuuuuuuuuuuu': ('^19745', # LLLLLLLLLLLLLLLLLLLLLLLLLL. + '^21324', # MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM. + '^22831', # NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN. + '^17081', # OOOOOOOOOOOOOOOOOOOOO. + ), + 'eeeeeeeeeeeeee': ( + '^9416', # Reporter email. Not necessarily the reporter. + '^^3', # This appears to be the raw email field. + ), + 'cccccccccc': ('^21109', # PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP. + ), + } + """) + expected_formatted_code = textwrap.dedent("""\ + _A = { + 'cccccccccc': ('^^1',), + 'rrrrrrrrrrrrrrrrrrrrrrrrr': ( + '^7913', # AAAAAAAAAAAAAA. + ), + 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee': ( + '^6242', # BBBBBBBBBBBBBBB. + ), + 'vvvvvvvvvvvvvvvvvvv': ( + '^27959', # CCCCCCCCCCCCCCCCCC. + '^19746', # DDDDDDDDDDDDDDDDDDDDDDD. + '^22907', # EEEEEEEEEEEEEEEEEEEEEEEE. + '^21098', # FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF. + '^22826', # GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG. + '^22769', # HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH. + '^22935', # IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII. + '^3982', # JJJJJJJJJJJJJ. + ), + 'uuuuuuuuuuuu': ( + '^19745', # LLLLLLLLLLLLLLLLLLLLLLLLLL. + '^21324', # MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM. + '^22831', # NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN. + '^17081', # OOOOOOOOOOOOOOOOOOOOO. + ), + 'eeeeeeeeeeeeee': ( + '^9416', # Reporter email. Not necessarily the reporter. + '^^3', # This appears to be the raw email field. + ), + 'cccccccccc': ( + '^21109', # PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP. + ), + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testNestedDictionary(self): + unformatted_code = textwrap.dedent("""\ + class _(): + def _(): + breadcrumbs = [{'name': 'Admin', + 'url': url_for(".home")}, + {'title': title},] + breadcrumbs = [{'name': 'Admin', + 'url': url_for(".home")}, + {'title': title}] + """) + expected_formatted_code = textwrap.dedent("""\ + class _(): + def _(): + breadcrumbs = [ + { + 'name': 'Admin', + 'url': url_for(".home") + }, + { + 'title': title + }, + ] + breadcrumbs = [{'name': 'Admin', 'url': url_for(".home")}, {'title': title}] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testDictionaryElementsOnOneLine(self): + code = textwrap.dedent("""\ + class _(): + + @mock.patch.dict( + os.environ, + {'HTTP_' + xsrf._XSRF_TOKEN_HEADER.replace('-', '_'): 'atoken'}) + def _(): + pass + + + AAAAAAAAAAAAAAAAAAAAAAAA = { + Environment.XXXXXXXXXX: 'some text more text even more tex', + Environment.YYYYYYY: 'some text more text even more text yet ag', + Environment.ZZZZZZZZZZZ: 'some text more text even mor etext yet again tex', + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testNotInParams(self): + unformatted_code = textwrap.dedent("""\ + list("a long line to break the line. a long line to break the brk a long lin", not True) + """) + expected_code = textwrap.dedent("""\ + list("a long line to break the line. a long line to break the brk a long lin", + not True) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_code, reformatter.Reformat(uwlines)) + + def testNamedAssignNotAtEndOfLine(self): + unformatted_code = textwrap.dedent("""\ + def _(): + if True: + with py3compat.open_with_encoding(filename, mode='w', + encoding=encoding) as fd: + pass + """) + expected_code = textwrap.dedent("""\ + def _(): + if True: + with py3compat.open_with_encoding( + filename, mode='w', encoding=encoding) as fd: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_code, reformatter.Reformat(uwlines)) + + def testBlankLineBeforeClassDocstring(self): + unformatted_code = textwrap.dedent('''\ + class A: + + """Does something. + + Also, here are some details. + """ + + def __init__(self): + pass + ''') + expected_code = textwrap.dedent('''\ + class A: + """Does something. + + Also, here are some details. + """ + + def __init__(self): + pass + ''') + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent('''\ + class A: + + """Does something. + + Also, here are some details. + """ + + def __init__(self): + pass + ''') + expected_formatted_code = textwrap.dedent('''\ + class A: + + """Does something. + + Also, here are some details. + """ + + def __init__(self): + pass + ''') + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: yapf, ' + 'blank_line_before_class_docstring: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testBlankLineBeforeModuleDocstring(self): + unformatted_code = textwrap.dedent('''\ + #!/usr/bin/env python + # -*- coding: utf-8 name> -*- + + """Some module docstring.""" + + + def foobar(): + pass + ''') + expected_code = textwrap.dedent('''\ + #!/usr/bin/env python + # -*- coding: utf-8 name> -*- + """Some module docstring.""" + + + def foobar(): + pass + ''') + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent('''\ + #!/usr/bin/env python + # -*- coding: utf-8 name> -*- + """Some module docstring.""" + + + def foobar(): + pass + ''') + expected_formatted_code = textwrap.dedent('''\ + #!/usr/bin/env python + # -*- coding: utf-8 name> -*- + + """Some module docstring.""" + + + def foobar(): + pass + ''') + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: pep8, ' + 'blank_line_before_module_docstring: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testTupleCohesion(self): + unformatted_code = textwrap.dedent("""\ + def f(): + this_is_a_very_long_function_name(an_extremely_long_variable_name, ( + 'a string that may be too long %s' % 'M15')) + """) + expected_code = textwrap.dedent("""\ + def f(): + this_is_a_very_long_function_name( + an_extremely_long_variable_name, + ('a string that may be too long %s' % 'M15')) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_code, reformatter.Reformat(uwlines)) + + def testSubscriptExpression(self): + code = textwrap.dedent("""\ + foo = d[not a] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testListWithFunctionCalls(self): + unformatted_code = textwrap.dedent("""\ + def foo(): + return [ + Bar( + xxx='some string', + yyy='another long string', + zzz='a third long string'), Bar( + xxx='some string', + yyy='another long string', + zzz='a third long string') + ] + """) + expected_code = textwrap.dedent("""\ + def foo(): + return [ + Bar(xxx='some string', + yyy='another long string', + zzz='a third long string'), + Bar(xxx='some string', + yyy='another long string', + zzz='a third long string') + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_code, reformatter.Reformat(uwlines)) + + def testEllipses(self): + unformatted_code = textwrap.dedent("""\ + X=... + Y = X if ... else X + """) + expected_code = textwrap.dedent("""\ + X = ... + Y = X if ... else X + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_code, reformatter.Reformat(uwlines)) + + def testPseudoParens(self): + unformatted_code = """\ +my_dict = { + 'key': # Some comment about the key + {'nested_key': 1, }, +} +""" + expected_code = """\ +my_dict = { + 'key': # Some comment about the key + { + 'nested_key': 1, + }, +} +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_code, reformatter.Reformat(uwlines)) + + def testSplittingBeforeFirstArgumentOnFunctionCall(self): + """Tests split_before_first_argument on a function call.""" + unformatted_code = textwrap.dedent("""\ + a_very_long_function_name("long string with formatting {0:s}".format( + "mystring")) + """) + expected_formatted_code = textwrap.dedent("""\ + a_very_long_function_name( + "long string with formatting {0:s}".format("mystring")) + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: yapf, split_before_first_argument: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testSplittingBeforeFirstArgumentOnFunctionDefinition(self): + """Tests split_before_first_argument on a function definition.""" + unformatted_code = textwrap.dedent("""\ + def _GetNumberOfSecondsFromElements(year, month, day, hours, + minutes, seconds, microseconds): + return + """) + expected_formatted_code = textwrap.dedent("""\ + def _GetNumberOfSecondsFromElements( + year, month, day, hours, minutes, seconds, microseconds): + return + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: yapf, split_before_first_argument: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testSplittingBeforeFirstArgumentOnCompoundStatement(self): + """Tests split_before_first_argument on a compound statement.""" + unformatted_code = textwrap.dedent("""\ + if (long_argument_name_1 == 1 or + long_argument_name_2 == 2 or + long_argument_name_3 == 3 or + long_argument_name_4 == 4): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + if (long_argument_name_1 == 1 or long_argument_name_2 == 2 or + long_argument_name_3 == 3 or long_argument_name_4 == 4): + pass + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: yapf, split_before_first_argument: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testCoalesceBracketsOnDict(self): + """Tests coalesce_brackets on a dictionary.""" + unformatted_code = textwrap.dedent("""\ + date_time_values = ( + { + u'year': year, + u'month': month, + u'day_of_month': day_of_month, + u'hours': hours, + u'minutes': minutes, + u'seconds': seconds + } + ) + """) + expected_formatted_code = textwrap.dedent("""\ + date_time_values = ({ + u'year': year, + u'month': month, + u'day_of_month': day_of_month, + u'hours': hours, + u'minutes': minutes, + u'seconds': seconds + }) + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: yapf, coalesce_brackets: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testSplitAfterComment(self): + code = textwrap.dedent("""\ + if __name__ == "__main__": + with another_resource: + account = { + "validUntil": + int(time() + (6 * 7 * 24 * 60 * 60)) # in 6 weeks time + } + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: yapf, coalesce_brackets: True, ' + 'dedent_closing_brackets: true}')) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + @unittest.skipUnless(not py3compat.PY3, 'Requires Python 2.7') + def testAsyncAsNonKeyword(self): + try: + style.SetGlobalStyle(style.CreatePEP8Style()) + + # In Python 2, async may be used as a non-keyword identifier. + code = textwrap.dedent("""\ + from util import async + + + class A(object): + def foo(self): + async.run() + """) + + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testDisableEndingCommaHeuristic(self): + code = textwrap.dedent("""\ + x = [1, 2, 3, 4, 5, 6, 7,] + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig('{based_on_style: yapf,' + ' disable_ending_comma_heuristic: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testDedentClosingBracketsWithTypeAnnotationExceedingLineLength(self): + unformatted_code = textwrap.dedent("""\ + def function(first_argument_xxxxxxxxxxxxxxxx=(0,), second_argument=None) -> None: + pass + + + def function(first_argument_xxxxxxxxxxxxxxxxxxxxxxx=(0,), second_argument=None) -> None: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def function( + first_argument_xxxxxxxxxxxxxxxx=(0,), second_argument=None + ) -> None: + pass + + + def function( + first_argument_xxxxxxxxxxxxxxxxxxxxxxx=(0,), second_argument=None + ) -> None: + pass + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig('{based_on_style: yapf,' + ' dedent_closing_brackets: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testIndentClosingBracketsWithTypeAnnotationExceedingLineLength(self): + unformatted_code = textwrap.dedent("""\ + def function(first_argument_xxxxxxxxxxxxxxxx=(0,), second_argument=None) -> None: + pass + + + def function(first_argument_xxxxxxxxxxxxxxxxxxxxxxx=(0,), second_argument=None) -> None: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def function( + first_argument_xxxxxxxxxxxxxxxx=(0,), second_argument=None + ) -> None: + pass + + + def function( + first_argument_xxxxxxxxxxxxxxxxxxxxxxx=(0,), second_argument=None + ) -> None: + pass + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig('{based_on_style: yapf,' + ' indent_closing_brackets: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testIndentClosingBracketsInFunctionCall(self): + unformatted_code = textwrap.dedent("""\ + def function(first_argument_xxxxxxxxxxxxxxxx=(0,), second_argument=None, third_and_final_argument=True): + pass + + + def function(first_argument_xxxxxxxxxxxxxxxxxxxxxxx=(0,), second_and_last_argument=None): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def function( + first_argument_xxxxxxxxxxxxxxxx=(0,), + second_argument=None, + third_and_final_argument=True + ): + pass + + + def function( + first_argument_xxxxxxxxxxxxxxxxxxxxxxx=(0,), second_and_last_argument=None + ): + pass + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig('{based_on_style: yapf,' + ' indent_closing_brackets: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testIndentClosingBracketsInTuple(self): + unformatted_code = textwrap.dedent("""\ + def function(): + some_var = ('a long element', 'another long element', 'short element', 'really really long element') + return True + + def function(): + some_var = ('a couple', 'small', 'elemens') + return False + """) + expected_formatted_code = textwrap.dedent("""\ + def function(): + some_var = ( + 'a long element', 'another long element', 'short element', + 'really really long element' + ) + return True + + + def function(): + some_var = ('a couple', 'small', 'elemens') + return False + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig('{based_on_style: yapf,' + ' indent_closing_brackets: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testIndentClosingBracketsInList(self): + unformatted_code = textwrap.dedent("""\ + def function(): + some_var = ['a long element', 'another long element', 'short element', 'really really long element'] + return True + + def function(): + some_var = ['a couple', 'small', 'elemens'] + return False + """) + expected_formatted_code = textwrap.dedent("""\ + def function(): + some_var = [ + 'a long element', 'another long element', 'short element', + 'really really long element' + ] + return True + + + def function(): + some_var = ['a couple', 'small', 'elemens'] + return False + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig('{based_on_style: yapf,' + ' indent_closing_brackets: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testIndentClosingBracketsInDict(self): + unformatted_code = textwrap.dedent("""\ + def function(): + some_var = {1: ('a long element', 'and another really really long element that is really really amazingly long'), 2: 'another long element', 3: 'short element', 4: 'really really long element'} + return True + + def function(): + some_var = {1: 'a couple', 2: 'small', 3: 'elemens'} + return False + """) + expected_formatted_code = textwrap.dedent("""\ + def function(): + some_var = { + 1: + ( + 'a long element', + 'and another really really long element that is really really amazingly long' + ), + 2: 'another long element', + 3: 'short element', + 4: 'really really long element' + } + return True + + + def function(): + some_var = {1: 'a couple', 2: 'small', 3: 'elemens'} + return False + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig('{based_on_style: yapf,' + ' indent_closing_brackets: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testMultipleDictionariesInList(self): + unformatted_code = textwrap.dedent("""\ + class A: + def b(): + d = { + "123456": [ + { + "12": "aa" + }, + { + "12": "bb" + }, + { + "12": "cc", + "1234567890": { + "1234567": [{ + "12": "dd", + "12345": "text 1" + }, { + "12": "ee", + "12345": "text 2" + }] + } + } + ] + } + """) + expected_formatted_code = textwrap.dedent("""\ + class A: + + def b(): + d = { + "123456": [{ + "12": "aa" + }, { + "12": "bb" + }, { + "12": "cc", + "1234567890": { + "1234567": [{ + "12": "dd", + "12345": "text 1" + }, { + "12": "ee", + "12345": "text 2" + }] + } + }] + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testForceMultilineDict_True(self): + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig('{force_multiline_dict: true}')) + unformatted_code = textwrap.dedent( + "responseDict = {'childDict': {'spam': 'eggs'}}\n") + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + actual = reformatter.Reformat(uwlines) + expected = textwrap.dedent("""\ + responseDict = { + 'childDict': { + 'spam': 'eggs' + } + } + """) + self.assertCodeEqual(expected, actual) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testForceMultilineDict_False(self): + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig('{force_multiline_dict: false}')) + unformatted_code = textwrap.dedent("""\ + responseDict = {'childDict': {'spam': 'eggs'}} + """) + expected_formatted_code = unformatted_code + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + @unittest.skipUnless(py3compat.PY38, 'Requires Python 3.8') + def testWalrus(self): + unformatted_code = textwrap.dedent("""\ + if (x := len([1]*1000)>100): + print(f'{x} is pretty big' ) + """) + expected = textwrap.dedent("""\ + if (x := len([1] * 1000) > 100): + print(f'{x} is pretty big') + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected, reformatter.Reformat(uwlines)) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_buganizer_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_buganizer_test.py new file mode 100644 index 00000000..e96f6da7 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_buganizer_test.py @@ -0,0 +1,2350 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Buganizer tests for yapf.reformatter.""" + +import textwrap +import unittest + +from yapf.yapflib import reformatter +from yapf.yapflib import style + +from yapftests import yapf_test_helper + + +class BuganizerFixes(yapf_test_helper.YAPFTest): + + @classmethod + def setUpClass(cls): + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testB137580392(self): + code = """\ +def _create_testing_simulator_and_sink( +) -> Tuple[_batch_simulator:_batch_simulator.BatchSimulator, + _batch_simulator.SimulationSink]: + pass +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB73279849(self): + unformatted_code = """\ +class A: + def _(a): + return 'hello' [ a ] +""" + expected_formatted_code = """\ +class A: + def _(a): + return 'hello'[a] +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB122455211(self): + unformatted_code = """\ +_zzzzzzzzzzzzzzzzzzzz = Union[sssssssssssssssssssss.pppppppppppppppp, + sssssssssssssssssssss.pppppppppppppppppppppppppppp] +""" + expected_formatted_code = """\ +_zzzzzzzzzzzzzzzzzzzz = Union[ + sssssssssssssssssssss.pppppppppppppppp, + sssssssssssssssssssss.pppppppppppppppppppppppppppp] +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB119300344(self): + code = """\ +def _GenerateStatsEntries( + process_id: Text, + timestamp: Optional[rdfvalue.RDFDatetime] = None +) -> Sequence[stats_values.StatsStoreEntry]: + pass +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB132886019(self): + code = """\ +X = { + 'some_dict_key': + frozenset([ + # pylint: disable=line-too-long + '//this/path/is/really/too/long/for/this/line/and/probably/should/be/split', + ]), +} +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB26521719(self): + code = """\ +class _(): + + def _(self): + self.stubs.Set(some_type_of_arg, 'ThisIsAStringArgument', + lambda *unused_args, **unused_kwargs: fake_resolver) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB122541552(self): + code = """\ +# pylint: disable=g-explicit-bool-comparison,singleton-comparison +_QUERY = account.Account.query(account.Account.enabled == True) +# pylint: enable=g-explicit-bool-comparison,singleton-comparison + + +def _(): + pass +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB124415889(self): + code = """\ +class _(): + + def run_queue_scanners(): + return xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + { + components.NAME.FNOR: True, + components.NAME.DEVO: True, + }, + default=False) + + def modules_to_install(): + modules = DeepCopy(GetDef({})) + modules.update({ + 'xxxxxxxxxxxxxxxxxxxx': + GetDef('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz', None), + }) + return modules +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB73166511(self): + code = """\ +def _(): + if min_std is not None: + groundtruth_age_variances = tf.maximum(groundtruth_age_variances, + min_std**2) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB118624921(self): + code = """\ +def _(): + function_call( + alert_name='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + time_delta='1h', + alert_level='bbbbbbbb', + metric='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + bork=foo) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB35417079(self): + code = """\ +class _(): + + def _(): + X = ( + _ares_label_prefix + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' # pylint: disable=line-too-long + 'PyTypePyTypePyTypePyTypePyTypePyTypePyTypePyTypePyTypePyTypePyTypePyTypePyType' # pytype: disable=attribute-error + 'CopybaraCopybaraCopybaraCopybaraCopybaraCopybaraCopybaraCopybaraCopybara' # copybara:strip + ) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB120047670(self): + unformatted_code = """\ +X = { + 'NO_PING_COMPONENTS': [ + 79775, # Releases / FOO API + 79770, # Releases / BAZ API + 79780], # Releases / MUX API + + 'PING_BLOCKED_BUGS': False, +} +""" + expected_formatted_code = """\ +X = { + 'NO_PING_COMPONENTS': [ + 79775, # Releases / FOO API + 79770, # Releases / BAZ API + 79780 + ], # Releases / MUX API + 'PING_BLOCKED_BUGS': False, +} +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB120245013(self): + unformatted_code = """\ +class Foo(object): + def testNoAlertForShortPeriod(self, rutabaga): + self.targets[:][streamz_path,self._fillInOtherFields(streamz_path, {streamz_field_of_interest:True})] = series.Counter('1s', '+ 500x10000') +""" + expected_formatted_code = """\ +class Foo(object): + + def testNoAlertForShortPeriod(self, rutabaga): + self.targets[:][ + streamz_path, + self._fillInOtherFields(streamz_path, {streamz_field_of_interest: True} + )] = series.Counter('1s', '+ 500x10000') +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB117841880(self): + code = """\ +def xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( + aaaaaaaaaaaaaaaaaaa: AnyStr, + bbbbbbbbbbbb: Optional[Sequence[AnyStr]] = None, + cccccccccc: AnyStr = cst.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD, + dddddddddd: Sequence[SliceDimension] = (), + eeeeeeeeeeee: AnyStr = cst.DEFAULT_CONTROL_NAME, + ffffffffffffffffffff: Optional[Callable[[pd.DataFrame], + pd.DataFrame]] = None, + gggggggggggggg: ooooooooooooo = ooooooooooooo() +) -> pd.DataFrame: + pass +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB111764402(self): + unformatted_code = """\ +x = self.stubs.stub(video_classification_map, 'read_video_classifications', (lambda external_ids, **unused_kwargs: {external_id: self._get_serving_classification('video') for external_id in external_ids})) +""" + expected_formatted_code = """\ +x = self.stubs.stub(video_classification_map, 'read_video_classifications', + (lambda external_ids, **unused_kwargs: { + external_id: self._get_serving_classification('video') + for external_id in external_ids + })) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB116825060(self): + code = """\ +result_df = pd.DataFrame({LEARNED_CTR_COLUMN: learned_ctr}, + index=df_metrics.index) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB112711217(self): + code = """\ +def _(): + stats['moderated'] = ~stats.moderation_reason.isin( + approved_moderation_reasons) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB112867548(self): + unformatted_code = """\ +def _(): + return flask.make_response( + 'Records: {}, Problems: {}, More: {}'.format( + process_result.result_ct, process_result.problem_ct, + process_result.has_more), + httplib.ACCEPTED if process_result.has_more else httplib.OK, + {'content-type': _TEXT_CONTEXT_TYPE}) +""" + expected_formatted_code = """\ +def _(): + return flask.make_response( + 'Records: {}, Problems: {}, More: {}'.format(process_result.result_ct, + process_result.problem_ct, + process_result.has_more), + httplib.ACCEPTED if process_result.has_more else httplib.OK, + {'content-type': _TEXT_CONTEXT_TYPE}) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB112651423(self): + unformatted_code = """\ +def potato(feeditems, browse_use_case=None): + for item in turnip: + if kumquat: + if not feeds_variants.variants['FEEDS_LOAD_PLAYLIST_VIDEOS_FOR_ALL_ITEMS'] and item.video: + continue +""" + expected_formatted_code = """\ +def potato(feeditems, browse_use_case=None): + for item in turnip: + if kumquat: + if not feeds_variants.variants[ + 'FEEDS_LOAD_PLAYLIST_VIDEOS_FOR_ALL_ITEMS'] and item.video: + continue +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB80484938(self): + code = """\ +for sssssss, aaaaaaaaaa in [ + ('ssssssssssssssssssss', 'sssssssssssssssssssssssss'), + ('nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn', + 'nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn'), + ('pppppppppppppppppppppppppppp', 'pppppppppppppppppppppppppppppppp'), + ('wwwwwwwwwwwwwwwwwwww', 'wwwwwwwwwwwwwwwwwwwwwwwww'), + ('sssssssssssssssss', 'sssssssssssssssssssssss'), + ('ggggggggggggggggggggggg', 'gggggggggggggggggggggggggggg'), + ('ggggggggggggggggg', 'gggggggggggggggggggggg'), + ('eeeeeeeeeeeeeeeeeeeeee', 'eeeeeeeeeeeeeeeeeeeeeeeeeee') +]: + pass + +for sssssss, aaaaaaaaaa in [ + ('ssssssssssssssssssss', 'sssssssssssssssssssssssss'), + ('nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn', 'nnnnnnnnnnnnnnnnnnnnnnnnn'), + ('pppppppppppppppppppppppppppp', 'pppppppppppppppppppppppppppppppp'), + ('wwwwwwwwwwwwwwwwwwww', 'wwwwwwwwwwwwwwwwwwwwwwwww'), + ('sssssssssssssssss', 'sssssssssssssssssssssss'), + ('ggggggggggggggggggggggg', 'gggggggggggggggggggggggggggg'), + ('ggggggggggggggggg', 'gggggggggggggggggggggg'), + ('eeeeeeeeeeeeeeeeeeeeee', 'eeeeeeeeeeeeeeeeeeeeeeeeeee') +]: + pass + +for sssssss, aaaaaaaaaa in [ + ('ssssssssssssssssssss', 'sssssssssssssssssssssssss'), + ('nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn', + 'nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn'), + ('pppppppppppppppppppppppppppp', 'pppppppppppppppppppppppppppppppp'), + ('wwwwwwwwwwwwwwwwwwww', 'wwwwwwwwwwwwwwwwwwwwwwwww'), + ('sssssssssssssssss', 'sssssssssssssssssssssss'), + ('ggggggggggggggggggggggg', 'gggggggggggggggggggggggggggg'), + ('ggggggggggggggggg', 'gggggggggggggggggggggg'), + ('eeeeeeeeeeeeeeeeeeeeee', 'eeeeeeeeeeeeeeeeeeeeeeeeeee'), +]: + pass +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB120771563(self): + code = """\ +class A: + + def b(): + d = { + "123456": [{ + "12": "aa" + }, { + "12": "bb" + }, { + "12": "cc", + "1234567890": { + "1234567": [{ + "12": "dd", + "12345": "text 1" + }, { + "12": "ee", + "12345": "text 2" + }] + } + }] + } +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB79462249(self): + code = """\ +foo.bar(baz, [ + quux(thud=42), + norf, +]) +foo.bar(baz, [ + quux(), + norf, +]) +foo.bar(baz, quux(thud=42), aaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbb, + ccccccccccccccccccc) +foo.bar( + baz, + quux(thud=42), + aaaaaaaaaaaaaaaaaaaaaa=1, + bbbbbbbbbbbbbbbbbbbbb=2, + ccccccccccccccccccc=3) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB113210278(self): + unformatted_code = """\ +def _(): + aaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccc(\ +eeeeeeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffffffffffffffffffffff.\ +ggggggggggggggggggggggggggggggggg.hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh()) +""" + expected_formatted_code = """\ +def _(): + aaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccc( + eeeeeeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffffffffffffffffffffff + .ggggggggggggggggggggggggggggggggg.hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh()) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB77923341(self): + code = """\ +def f(): + if (aaaaaaaaaaaaaa.bbbbbbbbbbbb.ccccc <= 0 and # pytype: disable=attribute-error + ddddddddddd.eeeeeeeee == constants.FFFFFFFFFFFFFF): + raise "yo" +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB77329955(self): + code = """\ +class _(): + + @parameterized.named_parameters( + ('ReadyExpiredSuccess', True, True, True, None, None), + ('SpannerUpdateFails', True, False, True, None, None), + ('ReadyNotExpired', False, True, True, True, None), + # ('ReadyNotExpiredNotHealthy', False, True, True, False, True), + # ('ReadyNotExpiredNotHealthyErrorFails', False, True, True, False, False + # ('ReadyNotExpiredNotHealthyUpdateFails', False, False, True, False, True + ) + def _(): + pass +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB65197969(self): + unformatted_code = """\ +class _(): + + def _(): + return timedelta(seconds=max(float(time_scale), small_interval) * + 1.41 ** min(num_attempts, 9)) +""" + expected_formatted_code = """\ +class _(): + + def _(): + return timedelta( + seconds=max(float(time_scale), small_interval) * + 1.41**min(num_attempts, 9)) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB65546221(self): + unformatted_code = """\ +SUPPORTED_PLATFORMS = ( + "centos-6", + "centos-7", + "ubuntu-1204-precise", + "ubuntu-1404-trusty", + "ubuntu-1604-xenial", + "debian-7-wheezy", + "debian-8-jessie", + "debian-9-stretch",) +""" + expected_formatted_code = """\ +SUPPORTED_PLATFORMS = ( + "centos-6", + "centos-7", + "ubuntu-1204-precise", + "ubuntu-1404-trusty", + "ubuntu-1604-xenial", + "debian-7-wheezy", + "debian-8-jessie", + "debian-9-stretch", +) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB30500455(self): + unformatted_code = """\ +INITIAL_SYMTAB = dict([(name, 'exception#' + name) for name in INITIAL_EXCEPTIONS +] * [(name, 'type#' + name) for name in INITIAL_TYPES] + [ + (name, 'function#' + name) for name in INITIAL_FUNCTIONS +] + [(name, 'const#' + name) for name in INITIAL_CONSTS]) +""" + expected_formatted_code = """\ +INITIAL_SYMTAB = dict( + [(name, 'exception#' + name) for name in INITIAL_EXCEPTIONS] * + [(name, 'type#' + name) for name in INITIAL_TYPES] + + [(name, 'function#' + name) for name in INITIAL_FUNCTIONS] + + [(name, 'const#' + name) for name in INITIAL_CONSTS]) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB38343525(self): + code = """\ +# This does foo. +@arg.String('some_path_to_a_file', required=True) +# This does bar. +@arg.String('some_path_to_a_file', required=True) +def f(): + print 1 +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB37099651(self): + unformatted_code = """\ +_MEMCACHE = lazy.MakeLazy( + # pylint: disable=g-long-lambda + lambda: function.call.mem.clients(FLAGS.some_flag_thingy, default_namespace=_LAZY_MEM_NAMESPACE, allow_pickle=True) + # pylint: enable=g-long-lambda +) +""" + expected_formatted_code = """\ +_MEMCACHE = lazy.MakeLazy( + # pylint: disable=g-long-lambda + lambda: function.call.mem.clients( + FLAGS.some_flag_thingy, + default_namespace=_LAZY_MEM_NAMESPACE, + allow_pickle=True) + # pylint: enable=g-long-lambda +) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB33228502(self): + unformatted_code = """\ +def _(): + success_rate_stream_table = module.Precompute( + query_function=module.DefineQueryFunction( + name='Response error ratio', + expression=((m.Fetch( + m.Raw('monarch.BorgTask', + '/corp/travel/trips2/dispatcher/email/response'), + {'borg_job': module_config.job, 'metric:response_type': 'SUCCESS'}), + m.Fetch(m.Raw('monarch.BorgTask', '/corp/travel/trips2/dispatcher/email/response'), {'borg_job': module_config.job})) + | m.Window(m.Delta('1h')) + | m.Join('successes', 'total') + | m.Point(m.VAL['successes'] / m.VAL['total'])))) +""" + expected_formatted_code = """\ +def _(): + success_rate_stream_table = module.Precompute( + query_function=module.DefineQueryFunction( + name='Response error ratio', + expression=( + (m.Fetch( + m.Raw('monarch.BorgTask', + '/corp/travel/trips2/dispatcher/email/response'), { + 'borg_job': module_config.job, + 'metric:response_type': 'SUCCESS' + }), + m.Fetch( + m.Raw('monarch.BorgTask', + '/corp/travel/trips2/dispatcher/email/response'), + {'borg_job': module_config.job})) + | m.Window(m.Delta('1h')) + | m.Join('successes', 'total') + | m.Point(m.VAL['successes'] / m.VAL['total'])))) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB30394228(self): + code = """\ +class _(): + + def _(self): + return some.randome.function.calling( + wf, None, alert.Format(alert.subject, alert=alert, threshold=threshold), + alert.Format(alert.body, alert=alert, threshold=threshold), + alert.html_formatting) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB65246454(self): + unformatted_code = """\ +class _(): + + def _(self): + self.assertEqual({i.id + for i in successful_instances}, + {i.id + for i in self._statuses.successful_instances}) +""" + expected_formatted_code = """\ +class _(): + + def _(self): + self.assertEqual({i.id for i in successful_instances}, + {i.id for i in self._statuses.successful_instances}) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB67935450(self): + unformatted_code = """\ +def _(): + return ( + (Gauge( + metric='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + group_by=group_by + ['metric:process_name'], + metric_filter={'metric:process_name': process_name_re}), + Gauge( + metric='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', + group_by=group_by + ['metric:process_name'], + metric_filter={'metric:process_name': process_name_re})) + | expr.Join( + left_name='start', left_default=0, right_name='end', right_default=0) + | m.Point( + m.Cond(m.VAL['end'] != 0, m.VAL['end'], k.TimestampMicros() / + 1000000L) - m.Cond(m.VAL['start'] != 0, m.VAL['start'], + m.TimestampMicros() / 1000000L))) +""" + expected_formatted_code = """\ +def _(): + return ( + (Gauge( + metric='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + group_by=group_by + ['metric:process_name'], + metric_filter={'metric:process_name': process_name_re}), + Gauge( + metric='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', + group_by=group_by + ['metric:process_name'], + metric_filter={'metric:process_name': process_name_re})) + | expr.Join( + left_name='start', left_default=0, right_name='end', right_default=0) + | m.Point( + m.Cond(m.VAL['end'] != 0, m.VAL['end'], + k.TimestampMicros() / 1000000L) - + m.Cond(m.VAL['start'] != 0, m.VAL['start'], + m.TimestampMicros() / 1000000L))) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB66011084(self): + unformatted_code = """\ +X = { +"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": # Comment 1. +([] if True else [ # Comment 2. + "bbbbbbbbbbbbbbbbbbb", # Comment 3. + "cccccccccccccccccccccccc", # Comment 4. + "ddddddddddddddddddddddddd", # Comment 5. + "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", # Comment 6. + "fffffffffffffffffffffffffffffff", # Comment 7. + "ggggggggggggggggggggggggggg", # Comment 8. + "hhhhhhhhhhhhhhhhhh", # Comment 9. +]), +} +""" + expected_formatted_code = """\ +X = { + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": # Comment 1. + ([] if True else [ # Comment 2. + "bbbbbbbbbbbbbbbbbbb", # Comment 3. + "cccccccccccccccccccccccc", # Comment 4. + "ddddddddddddddddddddddddd", # Comment 5. + "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", # Comment 6. + "fffffffffffffffffffffffffffffff", # Comment 7. + "ggggggggggggggggggggggggggg", # Comment 8. + "hhhhhhhhhhhhhhhhhh", # Comment 9. + ]), +} +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB67455376(self): + unformatted_code = """\ +sponge_ids.extend(invocation.id() for invocation in self._client.GetInvocationsByLabels(labels)) +""" + expected_formatted_code = """\ +sponge_ids.extend(invocation.id() + for invocation in self._client.GetInvocationsByLabels(labels)) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB35210351(self): + unformatted_code = """\ +def _(): + config.AnotherRuleThing( + 'the_title_to_the_thing_here', + {'monitorname': 'firefly', + 'service': ACCOUNTING_THING, + 'severity': 'the_bug', + 'monarch_module_name': alerts.TheLabel(qa_module_regexp, invert=True)}, + fanout, + alerts.AlertUsToSomething( + GetTheAlertToIt('the_title_to_the_thing_here'), + GetNotificationTemplate('your_email_here'))) +""" + expected_formatted_code = """\ +def _(): + config.AnotherRuleThing( + 'the_title_to_the_thing_here', { + 'monitorname': 'firefly', + 'service': ACCOUNTING_THING, + 'severity': 'the_bug', + 'monarch_module_name': alerts.TheLabel(qa_module_regexp, invert=True) + }, fanout, + alerts.AlertUsToSomething( + GetTheAlertToIt('the_title_to_the_thing_here'), + GetNotificationTemplate('your_email_here'))) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB34774905(self): + unformatted_code = """\ +x=[VarExprType(ir_name=IrName( value='x', +expr_type=UnresolvedAttrExprType( atom=UnknownExprType(), attr_name=IrName( + value='x', expr_type=UnknownExprType(), usage='UNKNOWN', fqn=None, + astn=None), usage='REF'), usage='ATTR', fqn='.x', astn=None))] +""" + expected_formatted_code = """\ +x = [ + VarExprType( + ir_name=IrName( + value='x', + expr_type=UnresolvedAttrExprType( + atom=UnknownExprType(), + attr_name=IrName( + value='x', + expr_type=UnknownExprType(), + usage='UNKNOWN', + fqn=None, + astn=None), + usage='REF'), + usage='ATTR', + fqn='.x', + astn=None)) +] +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB65176185(self): + code = """\ +xx = zip(*[(a, b) for (a, b, c) in yy]) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB35210166(self): + unformatted_code = """\ +def _(): + query = ( + m.Fetch(n.Raw('monarch.BorgTask', '/proc/container/memory/usage'), { 'borg_user': borguser, 'borg_job': jobname }) + | o.Window(m.Align('5m')) | p.GroupBy(['borg_user', 'borg_job', 'borg_cell'], q.Mean())) +""" + expected_formatted_code = """\ +def _(): + query = ( + m.Fetch( + n.Raw('monarch.BorgTask', '/proc/container/memory/usage'), { + 'borg_user': borguser, + 'borg_job': jobname + }) + | o.Window(m.Align('5m')) + | p.GroupBy(['borg_user', 'borg_job', 'borg_cell'], q.Mean())) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB32167774(self): + unformatted_code = """\ +X = ( + 'is_official', + 'is_cover', + 'is_remix', + 'is_instrumental', + 'is_live', + 'has_lyrics', + 'is_album', + 'is_compilation',) +""" + expected_formatted_code = """\ +X = ( + 'is_official', + 'is_cover', + 'is_remix', + 'is_instrumental', + 'is_live', + 'has_lyrics', + 'is_album', + 'is_compilation', +) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB66912275(self): + unformatted_code = """\ +def _(): + with self.assertRaisesRegexp(errors.HttpError, 'Invalid'): + patch_op = api_client.forwardingRules().patch( + project=project_id, + region=region, + forwardingRule=rule_name, + body={'fingerprint': base64.urlsafe_b64encode('invalid_fingerprint')}).execute() +""" + expected_formatted_code = """\ +def _(): + with self.assertRaisesRegexp(errors.HttpError, 'Invalid'): + patch_op = api_client.forwardingRules().patch( + project=project_id, + region=region, + forwardingRule=rule_name, + body={ + 'fingerprint': base64.urlsafe_b64encode('invalid_fingerprint') + }).execute() +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB67312284(self): + code = """\ +def _(): + self.assertEqual( + [u'to be published 2', u'to be published 1', u'to be published 0'], + [el.text for el in page.first_column_tds]) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB65241516(self): + unformatted_code = """\ +checkpoint_files = gfile.Glob(os.path.join(TrainTraceDir(unit_key, "*", "*"), embedding_model.CHECKPOINT_FILENAME + "-*")) +""" + expected_formatted_code = """\ +checkpoint_files = gfile.Glob( + os.path.join( + TrainTraceDir(unit_key, "*", "*"), + embedding_model.CHECKPOINT_FILENAME + "-*")) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB37460004(self): + code = textwrap.dedent("""\ + assert all(s not in (_SENTINEL, None) for s in nested_schemas + ), 'Nested schemas should never contain None/_SENTINEL' + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB36806207(self): + code = """\ +def _(): + linearity_data = [[row] for row in [ + "%.1f mm" % (np.mean(linearity_values["pos_error"]) * 1000.0), + "%.1f mm" % (np.max(linearity_values["pos_error"]) * 1000.0), + "%.1f mm" % (np.mean(linearity_values["pos_error_chunk_mean"]) * 1000.0), + "%.1f mm" % (np.max(linearity_values["pos_error_chunk_max"]) * 1000.0), + "%.1f deg" % math.degrees(np.mean(linearity_values["rot_noise"])), + "%.1f deg" % math.degrees(np.max(linearity_values["rot_noise"])), + "%.1f deg" % math.degrees(np.mean(linearity_values["rot_drift"])), + "%.1f deg" % math.degrees(np.max(linearity_values["rot_drift"])), + "%.1f%%" % (np.max(linearity_values["pos_discontinuity"]) * 100.0), + "%.1f%%" % (np.max(linearity_values["rot_discontinuity"]) * 100.0) + ]] +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB36215507(self): + code = textwrap.dedent("""\ + class X(): + + def _(): + aaaaaaaaaaaaa._bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb( + mmmmmmmmmmmmm, nnnnn, ooooooooo, + _(ppppppppppppppppppppppppppppppppppppp), + *(qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq), + **(qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB35212469(self): + unformatted_code = textwrap.dedent("""\ + def _(): + X = { + 'retain': { + 'loadtest': # This is a comment in the middle of a dictionary entry + ('/some/path/to/a/file/that/is/needed/by/this/process') + } + } + """) + expected_formatted_code = textwrap.dedent("""\ + def _(): + X = { + 'retain': { + 'loadtest': # This is a comment in the middle of a dictionary entry + ('/some/path/to/a/file/that/is/needed/by/this/process') + } + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB31063453(self): + unformatted_code = textwrap.dedent("""\ + def _(): + while ((not mpede_proc) or ((time_time() - last_modified) < FLAGS_boot_idle_timeout)): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def _(): + while ((not mpede_proc) or + ((time_time() - last_modified) < FLAGS_boot_idle_timeout)): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB35021894(self): + unformatted_code = textwrap.dedent("""\ + def _(): + labelacl = Env(qa={ + 'read': 'name/some-type-of-very-long-name-for-reading-perms', + 'modify': 'name/some-other-type-of-very-long-name-for-modifying' + }, + prod={ + 'read': 'name/some-type-of-very-long-name-for-reading-perms', + 'modify': 'name/some-other-type-of-very-long-name-for-modifying' + }) + """) + expected_formatted_code = textwrap.dedent("""\ + def _(): + labelacl = Env( + qa={ + 'read': 'name/some-type-of-very-long-name-for-reading-perms', + 'modify': 'name/some-other-type-of-very-long-name-for-modifying' + }, + prod={ + 'read': 'name/some-type-of-very-long-name-for-reading-perms', + 'modify': 'name/some-other-type-of-very-long-name-for-modifying' + }) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB34682902(self): + unformatted_code = textwrap.dedent("""\ + logging.info("Mean angular velocity norm: %.3f", np.linalg.norm(np.mean(ang_vel_arr, axis=0))) + """) + expected_formatted_code = textwrap.dedent("""\ + logging.info("Mean angular velocity norm: %.3f", + np.linalg.norm(np.mean(ang_vel_arr, axis=0))) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB33842726(self): + unformatted_code = textwrap.dedent("""\ + class _(): + def _(): + hints.append(('hg tag -f -l -r %s %s # %s' % (short(ctx.node( + )), candidatetag, firstline))[:78]) + """) + expected_formatted_code = textwrap.dedent("""\ + class _(): + def _(): + hints.append(('hg tag -f -l -r %s %s # %s' % + (short(ctx.node()), candidatetag, firstline))[:78]) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB32931780(self): + unformatted_code = textwrap.dedent("""\ + environments = { + 'prod': { + # this is a comment before the first entry. + 'entry one': + 'an entry.', + # this is the comment before the second entry. + 'entry number 2.': + 'something', + # this is the comment before the third entry and it's a doozy. So big! + 'who': + 'allin', + # This is an entry that has a dictionary in it. It's ugly + 'something': { + 'page': ['this-is-a-page@xxxxxxxx.com', 'something-for-eml@xxxxxx.com'], + 'bug': ['bugs-go-here5300@xxxxxx.com'], + 'email': ['sometypeof-email@xxxxxx.com'], + }, + # a short comment + 'yolo!!!!!': + 'another-email-address@xxxxxx.com', + # this entry has an implicit string concatenation + 'implicit': + 'https://this-is-very-long.url-addr.com/' + '?something=something%20some%20more%20stuff..', + # A more normal entry. + '.....': + 'this is an entry', + } + } + """) + expected_formatted_code = textwrap.dedent("""\ + environments = { + 'prod': { + # this is a comment before the first entry. + 'entry one': 'an entry.', + # this is the comment before the second entry. + 'entry number 2.': 'something', + # this is the comment before the third entry and it's a doozy. So big! + 'who': 'allin', + # This is an entry that has a dictionary in it. It's ugly + 'something': { + 'page': [ + 'this-is-a-page@xxxxxxxx.com', 'something-for-eml@xxxxxx.com' + ], + 'bug': ['bugs-go-here5300@xxxxxx.com'], + 'email': ['sometypeof-email@xxxxxx.com'], + }, + # a short comment + 'yolo!!!!!': 'another-email-address@xxxxxx.com', + # this entry has an implicit string concatenation + 'implicit': 'https://this-is-very-long.url-addr.com/' + '?something=something%20some%20more%20stuff..', + # A more normal entry. + '.....': 'this is an entry', + } + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB33047408(self): + code = textwrap.dedent("""\ + def _(): + for sort in (sorts or []): + request['sorts'].append({ + 'field': { + 'user_field': sort + }, + 'order': 'ASCENDING' + }) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB32714745(self): + code = textwrap.dedent("""\ + class _(): + + def _BlankDefinition(): + '''Return a generic blank dictionary for a new field.''' + return { + 'type': '', + 'validation': '', + 'name': 'fieldname', + 'label': 'Field Label', + 'help': '', + 'initial': '', + 'required': False, + 'required_msg': 'Required', + 'invalid_msg': 'Please enter a valid value', + 'options': { + 'regex': '', + 'widget_attr': '', + 'choices_checked': '', + 'choices_count': '', + 'choices': {} + }, + 'isnew': True, + 'dirty': False, + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB32737279(self): + unformatted_code = textwrap.dedent("""\ + here_is_a_dict = { + 'key': + # Comment. + 'value' + } + """) + expected_formatted_code = textwrap.dedent("""\ + here_is_a_dict = { + 'key': # Comment. + 'value' + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB32570937(self): + code = textwrap.dedent("""\ + def _(): + if (job_message.ball not in ('*', ball) or + job_message.call not in ('*', call) or + job_message.mall not in ('*', job_name)): + return False + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB31937033(self): + code = textwrap.dedent("""\ + class _(): + + def __init__(self, metric, fields_cb=None): + self._fields_cb = fields_cb or (lambda *unused_args, **unused_kwargs: {}) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB31911533(self): + code = """\ +class _(): + + @parameterized.NamedParameters( + ('IncludingModInfoWithHeaderList', AAAA, aaaa), + ('IncludingModInfoWithoutHeaderList', BBBB, bbbbb), + ('ExcludingModInfoWithHeaderList', CCCCC, cccc), + ('ExcludingModInfoWithoutHeaderList', DDDDD, ddddd), + ) + def _(): + pass +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB31847238(self): + unformatted_code = textwrap.dedent("""\ + class _(): + + def aaaaa(self, bbbbb, cccccccccccccc=None): # TODO(who): pylint: disable=unused-argument + return 1 + + def xxxxx(self, yyyyy, zzzzzzzzzzzzzz=None): # A normal comment that runs over the column limit. + return 1 + """) + expected_formatted_code = textwrap.dedent("""\ + class _(): + + def aaaaa(self, bbbbb, cccccccccccccc=None): # TODO(who): pylint: disable=unused-argument + return 1 + + def xxxxx( + self, + yyyyy, + zzzzzzzzzzzzzz=None): # A normal comment that runs over the column limit. + return 1 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB30760569(self): + unformatted_code = textwrap.dedent("""\ + {'1234567890123456789012345678901234567890123456789012345678901234567890': + '1234567890123456789012345678901234567890'} + """) + expected_formatted_code = textwrap.dedent("""\ + { + '1234567890123456789012345678901234567890123456789012345678901234567890': + '1234567890123456789012345678901234567890' + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB26034238(self): + unformatted_code = textwrap.dedent("""\ + class Thing: + + def Function(self): + thing.Scrape('/aaaaaaaaa/bbbbbbbbbb/ccccc/dddd/eeeeeeeeeeeeee/ffffffffffffff').AndReturn(42) + """) + expected_formatted_code = textwrap.dedent("""\ + class Thing: + + def Function(self): + thing.Scrape( + '/aaaaaaaaa/bbbbbbbbbb/ccccc/dddd/eeeeeeeeeeeeee/ffffffffffffff' + ).AndReturn(42) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB30536435(self): + unformatted_code = textwrap.dedent("""\ + def main(unused_argv): + if True: + if True: + aaaaaaaaaaa.comment('import-from[{}] {} {}'.format( + bbbbbbbbb.usage, + ccccccccc.within, + imports.ddddddddddddddddddd(name_item.ffffffffffffffff))) + """) + expected_formatted_code = textwrap.dedent("""\ + def main(unused_argv): + if True: + if True: + aaaaaaaaaaa.comment('import-from[{}] {} {}'.format( + bbbbbbbbb.usage, ccccccccc.within, + imports.ddddddddddddddddddd(name_item.ffffffffffffffff))) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB30442148(self): + unformatted_code = textwrap.dedent("""\ + def lulz(): + return (some_long_module_name.SomeLongClassName. + some_long_attribute_name.some_long_method_name()) + """) + expected_formatted_code = textwrap.dedent("""\ + def lulz(): + return (some_long_module_name.SomeLongClassName.some_long_attribute_name + .some_long_method_name()) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB26868213(self): + unformatted_code = textwrap.dedent("""\ + def _(): + xxxxxxxxxxxxxxxxxxx = { + 'ssssss': {'ddddd': 'qqqqq', + 'p90': aaaaaaaaaaaaaaaaa, + 'p99': bbbbbbbbbbbbbbbbb, + 'lllllllllllll': yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy(),}, + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbb': { + 'ddddd': 'bork bork bork bo', + 'p90': wwwwwwwwwwwwwwwww, + 'p99': wwwwwwwwwwwwwwwww, + 'lllllllllllll': None, # use the default + } + } + """) + expected_formatted_code = textwrap.dedent("""\ + def _(): + xxxxxxxxxxxxxxxxxxx = { + 'ssssss': { + 'ddddd': 'qqqqq', + 'p90': aaaaaaaaaaaaaaaaa, + 'p99': bbbbbbbbbbbbbbbbb, + 'lllllllllllll': yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy(), + }, + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbb': { + 'ddddd': 'bork bork bork bo', + 'p90': wwwwwwwwwwwwwwwww, + 'p99': wwwwwwwwwwwwwwwww, + 'lllllllllllll': None, # use the default + } + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB30173198(self): + code = textwrap.dedent("""\ + class _(): + + def _(): + self.assertFalse( + evaluation_runner.get_larps_in_eval_set('these_arent_the_larps')) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB29908765(self): + code = textwrap.dedent("""\ + class _(): + + def __repr__(self): + return '' % ( + self._id, self._stub._stub.rpc_channel().target()) # pylint:disable=protected-access + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB30087362(self): + code = textwrap.dedent("""\ + def _(): + for s in sorted(env['foo']): + bar() + # This is a comment + + # This is another comment + foo() + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB30087363(self): + code = textwrap.dedent("""\ + if False: + bar() + # This is a comment + # This is another comment + elif True: + foo() + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB29093579(self): + unformatted_code = textwrap.dedent("""\ + def _(): + _xxxxxxxxxxxxxxx(aaaaaaaa, bbbbbbbbbbbbbb.cccccccccc[ + dddddddddddddddddddddddddddd.eeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffff]) + """) + expected_formatted_code = textwrap.dedent("""\ + def _(): + _xxxxxxxxxxxxxxx( + aaaaaaaa, + bbbbbbbbbbbbbb.cccccccccc[dddddddddddddddddddddddddddd + .eeeeeeeeeeeeeeeeeeeeee.fffffffffffffffffffff]) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB26382315(self): + code = textwrap.dedent("""\ + @hello_world + # This is a first comment + + # Comment + def foo(): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB27616132(self): + unformatted_code = textwrap.dedent("""\ + if True: + query.fetch_page.assert_has_calls([ + mock.call(100, + start_cursor=None), + mock.call(100, + start_cursor=cursor_1), + mock.call(100, + start_cursor=cursor_2), + ]) + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + query.fetch_page.assert_has_calls([ + mock.call(100, start_cursor=None), + mock.call(100, start_cursor=cursor_1), + mock.call(100, start_cursor=cursor_2), + ]) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB27590179(self): + unformatted_code = textwrap.dedent("""\ + if True: + if True: + self.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = ( + { True: + self.bbb.cccccccccc(ddddddddddddddddddddddd.eeeeeeeeeeeeeeeeeeeeee), + False: + self.bbb.cccccccccc(ddddddddddddddddddddddd.eeeeeeeeeeeeeeeeeeeeee) + }) + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + if True: + self.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = ({ + True: + self.bbb.cccccccccc(ddddddddddddddddddddddd.eeeeeeeeeeeeeeeeeeeeee), + False: + self.bbb.cccccccccc(ddddddddddddddddddddddd.eeeeeeeeeeeeeeeeeeeeee) + }) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB27266946(self): + unformatted_code = textwrap.dedent("""\ + def _(): + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = (self.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccccccccccc) + """) + expected_formatted_code = textwrap.dedent("""\ + def _(): + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = ( + self.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + .cccccccccccccccccccccccccccccccccccc) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB25505359(self): + code = textwrap.dedent("""\ + _EXAMPLE = { + 'aaaaaaaaaaaaaa': [{ + 'bbbb': 'cccccccccccccccccccccc', + 'dddddddddddd': [] + }, { + 'bbbb': 'ccccccccccccccccccc', + 'dddddddddddd': [] + }] + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB25324261(self): + code = textwrap.dedent("""\ + aaaaaaaaa = set(bbbb.cccc + for ddd in eeeeee.fffffffffff.gggggggggggggggg + for cccc in ddd.specification) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB25136704(self): + code = textwrap.dedent("""\ + class f: + + def test(self): + self.bbbbbbb[0]['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', { + 'xxxxxx': 'yyyyyy' + }] = cccccc.ddd('1m', '10x1+1') + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB25165602(self): + code = textwrap.dedent("""\ + def f(): + ids = {u: i for u, i in zip(self.aaaaa, xrange(42, 42 + len(self.aaaaaa)))} + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB25157123(self): + code = textwrap.dedent("""\ + def ListArgs(): + FairlyLongMethodName([relatively_long_identifier_for_a_list], + another_argument_with_a_long_identifier) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB25136820(self): + unformatted_code = textwrap.dedent("""\ + def foo(): + return collections.OrderedDict({ + # Preceding comment. + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa': + '$bbbbbbbbbbbbbbbbbbbbbbbb', + }) + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): + return collections.OrderedDict({ + # Preceding comment. + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa': + '$bbbbbbbbbbbbbbbbbbbbbbbb', + }) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB25131481(self): + unformatted_code = textwrap.dedent("""\ + APPARENT_ACTIONS = ('command_type', { + 'materialize': lambda x: some_type_of_function('materialize ' + x.command_def), + '#': lambda x: x # do nothing + }) + """) + expected_formatted_code = textwrap.dedent("""\ + APPARENT_ACTIONS = ( + 'command_type', + { + 'materialize': + lambda x: some_type_of_function('materialize ' + x.command_def), + '#': + lambda x: x # do nothing + }) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB23445244(self): + unformatted_code = textwrap.dedent("""\ + def foo(): + if True: + return xxxxxxxxxxxxxxxx( + command, + extra_env={ + "OOOOOOOOOOOOOOOOOOOOO": FLAGS.zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, + "PPPPPPPPPPPPPPPPPPPPP": + FLAGS.aaaaaaaaaaaaaa + FLAGS.bbbbbbbbbbbbbbbbbbb, + }) + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): + if True: + return xxxxxxxxxxxxxxxx( + command, + extra_env={ + "OOOOOOOOOOOOOOOOOOOOO": + FLAGS.zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, + "PPPPPPPPPPPPPPPPPPPPP": + FLAGS.aaaaaaaaaaaaaa + FLAGS.bbbbbbbbbbbbbbbbbbb, + }) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB20559654(self): + unformatted_code = textwrap.dedent("""\ + class A(object): + + def foo(self): + unused_error, result = server.Query( + ['AA BBBB CCC DDD EEEEEEEE X YY ZZZZ FFF EEE AAAAAAAA'], + aaaaaaaaaaa=True, bbbbbbbb=None) + """) + expected_formatted_code = textwrap.dedent("""\ + class A(object): + + def foo(self): + unused_error, result = server.Query( + ['AA BBBB CCC DDD EEEEEEEE X YY ZZZZ FFF EEE AAAAAAAA'], + aaaaaaaaaaa=True, + bbbbbbbb=None) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB23943842(self): + unformatted_code = textwrap.dedent("""\ + class F(): + def f(): + self.assertDictEqual( + accounts, { + 'foo': + {'account': 'foo', + 'lines': 'l1\\nl2\\nl3\\n1 line(s) were elided.'}, + 'bar': {'account': 'bar', + 'lines': 'l5\\nl6\\nl7'}, + 'wiz': {'account': 'wiz', + 'lines': 'l8'} + }) + """) + expected_formatted_code = textwrap.dedent("""\ + class F(): + + def f(): + self.assertDictEqual( + accounts, { + 'foo': { + 'account': 'foo', + 'lines': 'l1\\nl2\\nl3\\n1 line(s) were elided.' + }, + 'bar': { + 'account': 'bar', + 'lines': 'l5\\nl6\\nl7' + }, + 'wiz': { + 'account': 'wiz', + 'lines': 'l8' + } + }) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB20551180(self): + unformatted_code = textwrap.dedent("""\ + def foo(): + if True: + return (struct.pack('aaaa', bbbbbbbbbb, ccccccccccccccc, dddddddd) + eeeeeee) + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): + if True: + return (struct.pack('aaaa', bbbbbbbbbb, ccccccccccccccc, dddddddd) + + eeeeeee) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB23944849(self): + unformatted_code = textwrap.dedent("""\ + class A(object): + def xxxxxxxxx(self, aaaaaaa, bbbbbbb=ccccccccccc, dddddd=300, eeeeeeeeeeeeee=None, fffffffffffffff=0): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + class A(object): + + def xxxxxxxxx(self, + aaaaaaa, + bbbbbbb=ccccccccccc, + dddddd=300, + eeeeeeeeeeeeee=None, + fffffffffffffff=0): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB23935890(self): + unformatted_code = textwrap.dedent("""\ + class F(): + def functioni(self, aaaaaaa, bbbbbbb, cccccc, dddddddddddddd, eeeeeeeeeeeeeee): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + class F(): + + def functioni(self, aaaaaaa, bbbbbbb, cccccc, dddddddddddddd, + eeeeeeeeeeeeeee): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB28414371(self): + code = textwrap.dedent("""\ + def _(): + return ((m.fffff( + m.rrr('mmmmmmmmmmmmmmmm', 'ssssssssssssssssssssssssss'), ffffffffffffffff) + | m.wwwwww(m.ddddd('1h')) + | m.ggggggg(bbbbbbbbbbbbbbb) + | m.ppppp( + (1 - m.ffffffffffffffff(llllllllllllllllllllll * 1000000, m.vvv)) + * m.ddddddddddddddddd(m.vvv)), + m.fffff( + m.rrr('mmmmmmmmmmmmmmmm', 'sssssssssssssssssssssss'), + dict( + ffffffffffffffff, **{ + 'mmmmmm:ssssss': + m.rrrrrrrrrrr('|'.join(iiiiiiiiiiiiii), iiiiii=True) + })) + | m.wwwwww(m.rrrr('1h')) + | m.ggggggg(bbbbbbbbbbbbbbb)) + | m.jjjj() + | m.ppppp(m.vvv[0] + m.vvv[1])) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB20127686(self): + code = textwrap.dedent("""\ + def f(): + if True: + return ((m.fffff( + m.rrr('xxxxxxxxxxxxxxxx', + 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'), + mmmmmmmm) + | m.wwwwww(m.rrrr(self.tttttttttt, self.mmmmmmmmmmmmmmmmmmmmm)) + | m.ggggggg(self.gggggggg, m.sss()), m.fffff('aaaaaaaaaaaaaaaa') + | m.wwwwww(m.ddddd(self.tttttttttt, self.mmmmmmmmmmmmmmmmmmmmm)) + | m.ggggggg(self.gggggggg)) + | m.jjjj() + | m.ppppp(m.VAL[0] / m.VAL[1])) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB20016122(self): + unformatted_code = textwrap.dedent("""\ + from a_very_long_or_indented_module_name_yada_yada import (long_argument_1, + long_argument_2) + """) + expected_formatted_code = textwrap.dedent("""\ + from a_very_long_or_indented_module_name_yada_yada import ( + long_argument_1, long_argument_2) + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: pep8, split_penalty_import_names: 350}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + + code = textwrap.dedent("""\ + class foo(): + + def __eq__(self, other): + return (isinstance(other, type(self)) + and self.xxxxxxxxxxx == other.xxxxxxxxxxx + and self.xxxxxxxx == other.xxxxxxxx + and self.aaaaaaaaaaaa == other.aaaaaaaaaaaa + and self.bbbbbbbbbbb == other.bbbbbbbbbbb + and self.ccccccccccccccccc == other.ccccccccccccccccc + and self.ddddddddddddddddddddddd == other.ddddddddddddddddddddddd + and self.eeeeeeeeeeee == other.eeeeeeeeeeee + and self.ffffffffffffff == other.time_completed + and self.gggggg == other.gggggg and self.hhh == other.hhh + and len(self.iiiiiiii) == len(other.iiiiiiii) + and all(jjjjjjj in other.iiiiiiii for jjjjjjj in self.iiiiiiii)) + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig('{based_on_style: yapf, ' + 'split_before_logical_operator: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testB22527411(self): + unformatted_code = textwrap.dedent("""\ + def f(): + if True: + aaaaaa.bbbbbbbbbbbbbbbbbbbb[-1].cccccccccccccc.ddd().eeeeeeee(ffffffffffffff) + """) + expected_formatted_code = textwrap.dedent("""\ + def f(): + if True: + aaaaaa.bbbbbbbbbbbbbbbbbbbb[-1].cccccccccccccc.ddd().eeeeeeee( + ffffffffffffff) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB20849933(self): + unformatted_code = textwrap.dedent("""\ + def main(unused_argv): + if True: + aaaaaaaa = { + 'xxx': '%s/cccccc/ddddddddddddddddddd.jar' % + (eeeeee.FFFFFFFFFFFFFFFFFF), + } + """) + expected_formatted_code = textwrap.dedent("""\ + def main(unused_argv): + if True: + aaaaaaaa = { + 'xxx': + '%s/cccccc/ddddddddddddddddddd.jar' % (eeeeee.FFFFFFFFFFFFFFFFFF), + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB20813997(self): + code = textwrap.dedent("""\ + def myfunc_1(): + myarray = numpy.zeros((2, 2, 2)) + print(myarray[:, 1, :]) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB20605036(self): + code = textwrap.dedent("""\ + foo = { + 'aaaa': { + # A comment for no particular reason. + 'xxxxxxxx': 'bbbbbbbbb', + 'yyyyyyyyyyyyyyyyyy': 'cccccccccccccccccccccccccccccc' + 'dddddddddddddddddddddddddddddddddddddddddd', + } + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB20562732(self): + code = textwrap.dedent("""\ + foo = [ + # Comment about first list item + 'First item', + # Comment about second list item + 'Second item', + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB20128830(self): + code = textwrap.dedent("""\ + a = { + 'xxxxxxxxxxxxxxxxxxxx': { + 'aaaa': + 'mmmmmmm', + 'bbbbb': + 'mmmmmmmmmmmmmmmmmmmmm', + 'cccccccccc': [ + 'nnnnnnnnnnn', + 'ooooooooooo', + 'ppppppppppp', + 'qqqqqqqqqqq', + ], + }, + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB20073838(self): + code = textwrap.dedent("""\ + class DummyModel(object): + + def do_nothing(self, class_1_count): + if True: + class_0_count = num_votes - class_1_count + return ('{class_0_name}={class_0_count}, {class_1_name}={class_1_count}' + .format( + class_0_name=self.class_0_name, + class_0_count=class_0_count, + class_1_name=self.class_1_name, + class_1_count=class_1_count)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB19626808(self): + code = textwrap.dedent("""\ + if True: + aaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbb( + 'ccccccccccc', ddddddddd='eeeee').fffffffff([ggggggggggggggggggggg]) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB19547210(self): + code = textwrap.dedent("""\ + while True: + if True: + if True: + if True: + if xxxxxxxxxxxx.yyyyyyy(aa).zzzzzzz() not in ( + xxxxxxxxxxxx.yyyyyyyyyyyyyy.zzzzzzzz, + xxxxxxxxxxxx.yyyyyyyyyyyyyy.zzzzzzzz): + continue + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB19377034(self): + code = textwrap.dedent("""\ + def f(): + if (aaaaaaaaaaaaaaa.start >= aaaaaaaaaaaaaaa.end or + bbbbbbbbbbbbbbb.start >= bbbbbbbbbbbbbbb.end): + return False + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB19372573(self): + code = textwrap.dedent("""\ + def f(): + if a: return 42 + while True: + if b: continue + if c: break + return 0 + """) + + try: + style.SetGlobalStyle(style.CreatePEP8Style()) + + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreateYapfStyle()) + + def testB19353268(self): + code = textwrap.dedent("""\ + a = {1, 2, 3}[x] + b = {'foo': 42, 'bar': 37}['foo'] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB19287512(self): + unformatted_code = textwrap.dedent("""\ + class Foo(object): + + def bar(self): + with xxxxxxxxxx.yyyyy( + 'aaaaaaa.bbbbbbbb.ccccccc.dddddddddddddddddddd.eeeeeeeeeee', + fffffffffff=(aaaaaaa.bbbbbbbb.ccccccc.dddddddddddddddddddd + .Mmmmmmmmmmmmmmmmmm(-1, 'permission error'))): + self.assertRaises(nnnnnnnnnnnnnnnn.ooooo, ppppp.qqqqqqqqqqqqqqqqq) + """) + expected_formatted_code = textwrap.dedent("""\ + class Foo(object): + + def bar(self): + with xxxxxxxxxx.yyyyy( + 'aaaaaaa.bbbbbbbb.ccccccc.dddddddddddddddddddd.eeeeeeeeeee', + fffffffffff=( + aaaaaaa.bbbbbbbb.ccccccc.dddddddddddddddddddd.Mmmmmmmmmmmmmmmmmm( + -1, 'permission error'))): + self.assertRaises(nnnnnnnnnnnnnnnn.ooooo, ppppp.qqqqqqqqqqqqqqqqq) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB19194420(self): + code = textwrap.dedent("""\ + method.Set( + 'long argument goes here that causes the line to break', + lambda arg2=0.5: arg2) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB19073499(self): + code = """\ +instance = ( + aaaaaaa.bbbbbbb().ccccccccccccccccc().ddddddddddd({ + 'aa': 'context!' + }).eeeeeeeeeeeeeeeeeee({ # Inline comment about why fnord has the value 6. + 'fnord': 6 + })) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB18257115(self): + code = textwrap.dedent("""\ + if True: + if True: + self._Test(aaaa, bbbbbbb.cccccccccc, dddddddd, eeeeeeeeeee, + [ffff, ggggggggggg, hhhhhhhhhhhh, iiiiii, jjjj]) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB18256666(self): + code = textwrap.dedent("""\ + class Foo(object): + + def Bar(self): + aaaaa.bbbbbbb( + ccc='ddddddddddddddd', + eeee='ffffffffffffffffffffff-%s-%s' % (gggg, int(time.time())), + hhhhhh={ + 'iiiiiiiiiii': iiiiiiiiiii, + 'jjjj': jjjj.jjjjj(), + 'kkkkkkkkkkkk': kkkkkkkkkkkk, + }, + llllllllll=mmmmmm.nnnnnnnnnnnnnnnn) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB18256826(self): + code = textwrap.dedent("""\ + if True: + pass + # A multiline comment. + # Line two. + elif False: + pass + + if True: + pass + # A multiline comment. + # Line two. + elif False: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB18255697(self): + code = textwrap.dedent("""\ + AAAAAAAAAAAAAAA = { + 'XXXXXXXXXXXXXX': 4242, # Inline comment + # Next comment + 'YYYYYYYYYYYYYYYY': ['zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'], + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testB17534869(self): + unformatted_code = textwrap.dedent("""\ + if True: + self.assertLess(abs(time.time()-aaaa.bbbbbbbbbbb( + datetime.datetime.now())), 1) + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + self.assertLess( + abs(time.time() - aaaa.bbbbbbbbbbb(datetime.datetime.now())), 1) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB17489866(self): + unformatted_code = textwrap.dedent("""\ + def f(): + if True: + if True: + return aaaa.bbbbbbbbb(ccccccc=dddddddddddddd({('eeee', \ +'ffffffff'): str(j)})) + """) + expected_formatted_code = textwrap.dedent("""\ + def f(): + if True: + if True: + return aaaa.bbbbbbbbb( + ccccccc=dddddddddddddd({('eeee', 'ffffffff'): str(j)})) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB17133019(self): + unformatted_code = textwrap.dedent("""\ + class aaaaaaaaaaaaaa(object): + + def bbbbbbbbbb(self): + with io.open("/dev/null", "rb"): + with io.open(os.path.join(aaaaa.bbbbb.ccccccccccc, + DDDDDDDDDDDDDDD, + "eeeeeeeee ffffffffff" + ), "rb") as gggggggggggggggggggg: + print(gggggggggggggggggggg) + """) + expected_formatted_code = textwrap.dedent("""\ + class aaaaaaaaaaaaaa(object): + + def bbbbbbbbbb(self): + with io.open("/dev/null", "rb"): + with io.open( + os.path.join(aaaaa.bbbbb.ccccccccccc, DDDDDDDDDDDDDDD, + "eeeeeeeee ffffffffff"), "rb") as gggggggggggggggggggg: + print(gggggggggggggggggggg) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB17011869(self): + unformatted_code = textwrap.dedent("""\ + '''blah......''' + + class SomeClass(object): + '''blah.''' + + AAAAAAAAAAAA = { # Comment. + 'BBB': 1.0, + 'DDDDDDDD': 0.4811 + } + """) + expected_formatted_code = textwrap.dedent("""\ + '''blah......''' + + + class SomeClass(object): + '''blah.''' + + AAAAAAAAAAAA = { # Comment. + 'BBB': 1.0, + 'DDDDDDDD': 0.4811 + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB16783631(self): + unformatted_code = textwrap.dedent("""\ + if True: + with aaaaaaaaaaaaaa.bbbbbbbbbbbbb.ccccccc(ddddddddddddd, + eeeeeeeee=self.fffffffffffff + )as gggg: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + with aaaaaaaaaaaaaa.bbbbbbbbbbbbb.ccccccc( + ddddddddddddd, eeeeeeeee=self.fffffffffffff) as gggg: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB16572361(self): + unformatted_code = textwrap.dedent("""\ + def foo(self): + def bar(my_dict_name): + self.my_dict_name['foo-bar-baz-biz-boo-baa-baa'].IncrementBy.assert_called_once_with('foo_bar_baz_boo') + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(self): + + def bar(my_dict_name): + self.my_dict_name[ + 'foo-bar-baz-biz-boo-baa-baa'].IncrementBy.assert_called_once_with( + 'foo_bar_baz_boo') + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB15884241(self): + unformatted_code = textwrap.dedent("""\ + if 1: + if 1: + for row in AAAA: + self.create(aaaaaaaa="/aaa/bbbb/cccc/dddddd/eeeeeeeeeeeeeeeeeeeeeeeeee/%s" % row [0].replace(".foo", ".bar"), aaaaa=bbb[1], ccccc=bbb[2], dddd=bbb[3], eeeeeeeeeee=[s.strip() for s in bbb[4].split(",")], ffffffff=[s.strip() for s in bbb[5].split(",")], gggggg=bbb[6]) + """) + expected_formatted_code = textwrap.dedent("""\ + if 1: + if 1: + for row in AAAA: + self.create( + aaaaaaaa="/aaa/bbbb/cccc/dddddd/eeeeeeeeeeeeeeeeeeeeeeeeee/%s" % + row[0].replace(".foo", ".bar"), + aaaaa=bbb[1], + ccccc=bbb[2], + dddd=bbb[3], + eeeeeeeeeee=[s.strip() for s in bbb[4].split(",")], + ffffffff=[s.strip() for s in bbb[5].split(",")], + gggggg=bbb[6]) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB15697268(self): + unformatted_code = textwrap.dedent("""\ + def main(unused_argv): + ARBITRARY_CONSTANT_A = 10 + an_array_with_an_exceedingly_long_name = range(ARBITRARY_CONSTANT_A + 1) + ok = an_array_with_an_exceedingly_long_name[:ARBITRARY_CONSTANT_A] + bad_slice = map(math.sqrt, an_array_with_an_exceedingly_long_name[:ARBITRARY_CONSTANT_A]) + a_long_name_slicing = an_array_with_an_exceedingly_long_name[:ARBITRARY_CONSTANT_A] + bad_slice = ("I am a crazy, no good, string whats too long, etc." + " no really ")[:ARBITRARY_CONSTANT_A] + """) + expected_formatted_code = textwrap.dedent("""\ + def main(unused_argv): + ARBITRARY_CONSTANT_A = 10 + an_array_with_an_exceedingly_long_name = range(ARBITRARY_CONSTANT_A + 1) + ok = an_array_with_an_exceedingly_long_name[:ARBITRARY_CONSTANT_A] + bad_slice = map(math.sqrt, + an_array_with_an_exceedingly_long_name[:ARBITRARY_CONSTANT_A]) + a_long_name_slicing = an_array_with_an_exceedingly_long_name[: + ARBITRARY_CONSTANT_A] + bad_slice = ("I am a crazy, no good, string whats too long, etc." + + " no really ")[:ARBITRARY_CONSTANT_A] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB15597568(self): + unformatted_code = """\ +if True: + if True: + if True: + print(("Return code was %d" + (", and the process timed out." if did_time_out else ".")) % errorcode) +""" + expected_formatted_code = """\ +if True: + if True: + if True: + print(("Return code was %d" + + (", and the process timed out." if did_time_out else ".")) % + errorcode) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB15542157(self): + unformatted_code = textwrap.dedent("""\ + aaaaaaaaaaaa = bbbb.ccccccccccccccc(dddddd.eeeeeeeeeeeeee, ffffffffffffffffff, gggggg.hhhhhhhhhhhhhhhhh) + """) + expected_formatted_code = textwrap.dedent("""\ + aaaaaaaaaaaa = bbbb.ccccccccccccccc(dddddd.eeeeeeeeeeeeee, ffffffffffffffffff, + gggggg.hhhhhhhhhhhhhhhhh) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB15438132(self): + unformatted_code = textwrap.dedent("""\ + if aaaaaaa.bbbbbbbbbb: + cccccc.dddddddddd(eeeeeeeeeee=fffffffffffff.gggggggggggggggggg) + if hhhhhh.iiiii.jjjjjjjjjjjjj: + # This is a comment in the middle of it all. + kkkkkkk.llllllllll.mmmmmmmmmmmmm = True + if (aaaaaa.bbbbb.ccccccccccccc != ddddddd.eeeeeeeeee.fffffffffffff or + eeeeee.fffff.ggggggggggggggggggggggggggg() != hhhhhhh.iiiiiiiiii.jjjjjjjjjjjj): + aaaaaaaa.bbbbbbbbbbbb( + aaaaaa.bbbbb.cc, + dddddddddddd=eeeeeeeeeeeeeeeeeee.fffffffffffffffff( + gggggg.hh, + iiiiiiiiiiiiiiiiiii.jjjjjjjjjj.kkkkkkk, + lllll.mm), + nnnnnnnnnn=ooooooo.pppppppppp) + """) + expected_formatted_code = textwrap.dedent("""\ + if aaaaaaa.bbbbbbbbbb: + cccccc.dddddddddd(eeeeeeeeeee=fffffffffffff.gggggggggggggggggg) + if hhhhhh.iiiii.jjjjjjjjjjjjj: + # This is a comment in the middle of it all. + kkkkkkk.llllllllll.mmmmmmmmmmmmm = True + if (aaaaaa.bbbbb.ccccccccccccc != ddddddd.eeeeeeeeee.fffffffffffff or + eeeeee.fffff.ggggggggggggggggggggggggggg() != + hhhhhhh.iiiiiiiiii.jjjjjjjjjjjj): + aaaaaaaa.bbbbbbbbbbbb( + aaaaaa.bbbbb.cc, + dddddddddddd=eeeeeeeeeeeeeeeeeee.fffffffffffffffff( + gggggg.hh, iiiiiiiiiiiiiiiiiii.jjjjjjjjjj.kkkkkkk, lllll.mm), + nnnnnnnnnn=ooooooo.pppppppppp) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB14468247(self): + unformatted_code = """\ +call(a=1, + b=2, +) +""" + expected_formatted_code = """\ +call( + a=1, + b=2, +) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB14406499(self): + unformatted_code = textwrap.dedent("""\ + def foo1(parameter_1, parameter_2, parameter_3, parameter_4, \ +parameter_5, parameter_6): pass + """) + expected_formatted_code = textwrap.dedent("""\ + def foo1(parameter_1, parameter_2, parameter_3, parameter_4, parameter_5, + parameter_6): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB13900309(self): + unformatted_code = textwrap.dedent("""\ + self.aaaaaaaaaaa( # A comment in the middle of it all. + 948.0/3600, self.bbb.ccccccccccccccccccccc(dddddddddddddddd.eeee, True)) + """) + expected_formatted_code = textwrap.dedent("""\ + self.aaaaaaaaaaa( # A comment in the middle of it all. + 948.0 / 3600, self.bbb.ccccccccccccccccccccc(dddddddddddddddd.eeee, True)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + code = textwrap.dedent("""\ + aaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccccc( + DC_1, (CL - 50, CL), AAAAAAAA, BBBBBBBBBBBBBBBB, 98.0, + CCCCCCC).ddddddddd( # Look! A comment is here. + AAAAAAAA - (20 * 60 - 5)) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + aaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbb.ccccccccccccccccccccccccc().dddddddddddddddddddddddddd(1, 2, 3, 4) + """) + expected_formatted_code = textwrap.dedent("""\ + aaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbb.ccccccccccccccccccccccccc( + ).dddddddddddddddddddddddddd(1, 2, 3, 4) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + aaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbb.ccccccccccccccccccccccccc(x).dddddddddddddddddddddddddd(1, 2, 3, 4) + """) + expected_formatted_code = textwrap.dedent("""\ + aaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbb.ccccccccccccccccccccccccc( + x).dddddddddddddddddddddddddd(1, 2, 3, 4) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + aaaaaaaaaaaaaaaaaaaaaaaa(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx).dddddddddddddddddddddddddd(1, 2, 3, 4) + """) + expected_formatted_code = textwrap.dedent("""\ + aaaaaaaaaaaaaaaaaaaaaaaa( + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx).dddddddddddddddddddddddddd(1, 2, 3, 4) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + aaaaaaaaaaaaaaaaaaaaaaaa().bbbbbbbbbbbbbbbbbbbbbbbb().ccccccccccccccccccc().\ +dddddddddddddddddd().eeeeeeeeeeeeeeeeeeeee().fffffffffffffffff().gggggggggggggggggg() + """) + expected_formatted_code = textwrap.dedent("""\ + aaaaaaaaaaaaaaaaaaaaaaaa().bbbbbbbbbbbbbbbbbbbbbbbb().ccccccccccccccccccc( + ).dddddddddddddddddd().eeeeeeeeeeeeeeeeeeeee().fffffffffffffffff( + ).gggggggggggggggggg() + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testB67935687(self): + code = textwrap.dedent("""\ + Fetch( + Raw('monarch.BorgTask', '/union/row_operator_action_delay'), + {'borg_user': self.borg_user}) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + shelf_renderer.expand_text = text.translate_to_unicode( + expand_text % { + 'creator': creator + }) + """) + expected_formatted_code = textwrap.dedent("""\ + shelf_renderer.expand_text = text.translate_to_unicode(expand_text % + {'creator': creator}) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_facebook_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_facebook_test.py new file mode 100644 index 00000000..289aa853 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_facebook_test.py @@ -0,0 +1,432 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Facebook tests for yapf.reformatter.""" + +import textwrap +import unittest + +from yapf.yapflib import reformatter +from yapf.yapflib import style + +from yapftests import yapf_test_helper + + +class TestsForFacebookStyle(yapf_test_helper.YAPFTest): + + @classmethod + def setUpClass(cls): + style.SetGlobalStyle(style.CreateFacebookStyle()) + + def testNoNeedForLineBreaks(self): + unformatted_code = textwrap.dedent("""\ + def overly_long_function_name( + just_one_arg, **kwargs): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def overly_long_function_name(just_one_arg, **kwargs): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testDedentClosingBracket(self): + unformatted_code = textwrap.dedent("""\ + def overly_long_function_name( + first_argument_on_the_same_line, + second_argument_makes_the_line_too_long): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def overly_long_function_name( + first_argument_on_the_same_line, second_argument_makes_the_line_too_long + ): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testBreakAfterOpeningBracketIfContentsTooBig(self): + unformatted_code = textwrap.dedent("""\ + def overly_long_function_name(a, b, c, d, e, f, g, h, i, j, k, l, m, + n, o, p, q, r, s, t, u, v, w, x, y, z): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def overly_long_function_name( + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, \ +v, w, x, y, z + ): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testDedentClosingBracketWithComments(self): + unformatted_code = textwrap.dedent("""\ + def overly_long_function_name( + # comment about the first argument + first_argument_with_a_very_long_name_or_so, + # comment about the second argument + second_argument_makes_the_line_too_long): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def overly_long_function_name( + # comment about the first argument + first_argument_with_a_very_long_name_or_so, + # comment about the second argument + second_argument_makes_the_line_too_long + ): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testDedentImportAsNames(self): + code = textwrap.dedent("""\ + from module import ( + internal_function as function, + SOME_CONSTANT_NUMBER1, + SOME_CONSTANT_NUMBER2, + SOME_CONSTANT_NUMBER3, + ) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testDedentTestListGexp(self): + unformatted_code = textwrap.dedent("""\ + try: + pass + except ( + IOError, OSError, LookupError, RuntimeError, OverflowError + ) as exception: + pass + + try: + pass + except ( + IOError, OSError, LookupError, RuntimeError, OverflowError, + ) as exception: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + try: + pass + except ( + IOError, OSError, LookupError, RuntimeError, OverflowError + ) as exception: + pass + + try: + pass + except ( + IOError, + OSError, + LookupError, + RuntimeError, + OverflowError, + ) as exception: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testBrokenIdempotency(self): + # TODO(ambv): The following behaviour should be fixed. + pass0_code = textwrap.dedent("""\ + try: + pass + except (IOError, OSError, LookupError, RuntimeError, OverflowError) as exception: + pass + """) + pass1_code = textwrap.dedent("""\ + try: + pass + except ( + IOError, OSError, LookupError, RuntimeError, OverflowError + ) as exception: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(pass0_code) + self.assertCodeEqual(pass1_code, reformatter.Reformat(uwlines)) + + pass2_code = textwrap.dedent("""\ + try: + pass + except ( + IOError, OSError, LookupError, RuntimeError, OverflowError + ) as exception: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(pass1_code) + self.assertCodeEqual(pass2_code, reformatter.Reformat(uwlines)) + + def testIfExprHangingIndent(self): + unformatted_code = textwrap.dedent("""\ + if True: + if True: + if True: + if not self.frobbies and ( + self.foobars.counters['db.cheeses'] != 1 or + self.foobars.counters['db.marshmellow_skins'] != 1): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + if True: + if True: + if not self.frobbies and ( + self.foobars.counters['db.cheeses'] != 1 or + self.foobars.counters['db.marshmellow_skins'] != 1 + ): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSimpleDedenting(self): + unformatted_code = textwrap.dedent("""\ + if True: + self.assertEqual(result.reason_not_added, "current preflight is still running") + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + self.assertEqual( + result.reason_not_added, "current preflight is still running" + ) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testDedentingWithSubscripts(self): + unformatted_code = textwrap.dedent("""\ + class Foo: + class Bar: + @classmethod + def baz(cls, clues_list, effect, constraints, constraint_manager): + if clues_lists: + return cls.single_constraint_not(clues_lists, effect, constraints[0], constraint_manager) + + """) + expected_formatted_code = textwrap.dedent("""\ + class Foo: + class Bar: + @classmethod + def baz(cls, clues_list, effect, constraints, constraint_manager): + if clues_lists: + return cls.single_constraint_not( + clues_lists, effect, constraints[0], constraint_manager + ) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testDedentingCallsWithInnerLists(self): + code = textwrap.dedent("""\ + class _(): + def _(): + cls.effect_clues = { + 'effect': Clue((cls.effect_time, 'apache_host'), effect_line, 40) + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testDedentingListComprehension(self): + unformatted_code = textwrap.dedent("""\ + class Foo(): + def _pack_results_for_constraint_or(): + self.param_groups = dict( + ( + key + 1, ParamGroup(groups[key], default_converter) + ) for key in six.moves.range(len(groups)) + ) + + for combination in cls._clues_combinations(clues_lists): + if all( + cls._verify_constraint(combination, effect, constraint) + for constraint in constraints + ): + pass + + guessed_dict = dict( + ( + key, guessed_pattern_matches[key] + ) for key in six.moves.range(len(guessed_pattern_matches)) + ) + + content = "".join( + itertools.chain( + (first_line_fragment, ), lines_between, (last_line_fragment, ) + ) + ) + + rule = Rule( + [self.cause1, self.cause2, self.cause1, self.cause2], self.effect, constraints1, + Rule.LINKAGE_AND + ) + + assert sorted(log_type.files_to_parse) == [ + ('localhost', os.path.join(path, 'node_1.log'), super_parser), + ('localhost', os.path.join(path, 'node_2.log'), super_parser) + ] + """) + expected_formatted_code = textwrap.dedent("""\ + class Foo(): + def _pack_results_for_constraint_or(): + self.param_groups = dict( + (key + 1, ParamGroup(groups[key], default_converter)) + for key in six.moves.range(len(groups)) + ) + + for combination in cls._clues_combinations(clues_lists): + if all( + cls._verify_constraint(combination, effect, constraint) + for constraint in constraints + ): + pass + + guessed_dict = dict( + (key, guessed_pattern_matches[key]) + for key in six.moves.range(len(guessed_pattern_matches)) + ) + + content = "".join( + itertools.chain( + (first_line_fragment, ), lines_between, (last_line_fragment, ) + ) + ) + + rule = Rule( + [self.cause1, self.cause2, self.cause1, self.cause2], self.effect, + constraints1, Rule.LINKAGE_AND + ) + + assert sorted(log_type.files_to_parse) == [ + ('localhost', os.path.join(path, 'node_1.log'), super_parser), + ('localhost', os.path.join(path, 'node_2.log'), super_parser) + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testMustSplitDedenting(self): + code = textwrap.dedent("""\ + class _(): + def _(): + effect_line = FrontInput( + effect_line_offset, line_content, + LineSource('localhost', xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) + ) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testDedentIfConditional(self): + code = textwrap.dedent("""\ + class _(): + def _(): + if True: + if not self.frobbies and ( + self.foobars.counters['db.cheeses'] != 1 or + self.foobars.counters['db.marshmellow_skins'] != 1 + ): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testDedentSet(self): + code = textwrap.dedent("""\ + class _(): + def _(): + assert set(self.constraint_links.get_links()) == set( + [ + (2, 10, 100), + (2, 10, 200), + (2, 20, 100), + (2, 20, 200), + ] + ) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testDedentingInnerScope(self): + code = textwrap.dedent("""\ + class Foo(): + @classmethod + def _pack_results_for_constraint_or(cls, combination, constraints): + return cls._create_investigation_result( + (clue for clue in combination if not clue == Verifier.UNMATCHED), + constraints, InvestigationResult.OR + ) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + reformatted_code = reformatter.Reformat(uwlines) + self.assertCodeEqual(code, reformatted_code) + + uwlines = yapf_test_helper.ParseAndUnwrap(reformatted_code) + reformatted_code = reformatter.Reformat(uwlines) + self.assertCodeEqual(code, reformatted_code) + + def testCommentWithNewlinesInPrefix(self): + unformatted_code = textwrap.dedent("""\ + def foo(): + if 0: + return False + + + #a deadly comment + elif 1: + return True + + + print(foo()) + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): + if 0: + return False + + #a deadly comment + elif 1: + return True + + + print(foo()) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testIfStmtClosingBracket(self): + unformatted_code = """\ +if (isinstance(value , (StopIteration , StopAsyncIteration )) and exc.__cause__ is value_asdfasdfasdfasdfsafsafsafdasfasdfs): + return False +""" + expected_formatted_code = """\ +if ( + isinstance(value, (StopIteration, StopAsyncIteration)) and + exc.__cause__ is value_asdfasdfasdfasdfsafsafsafdasfasdfs +): + return False +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_pep8_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_pep8_test.py new file mode 100644 index 00000000..bdd074a7 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_pep8_test.py @@ -0,0 +1,919 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""PEP8 tests for yapf.reformatter.""" + +import textwrap +import unittest + +from yapf.yapflib import py3compat +from yapf.yapflib import reformatter +from yapf.yapflib import style + +from yapftests import yapf_test_helper + + +class TestsForPEP8Style(yapf_test_helper.YAPFTest): + + @classmethod + def setUpClass(cls): # pylint: disable=g-missing-super-call + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testIndent4(self): + unformatted_code = textwrap.dedent("""\ + if a+b: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + if a + b: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSingleLineIfStatements(self): + code = textwrap.dedent("""\ + if True: a = 42 + elif False: b = 42 + else: c = 42 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testNoBlankBetweenClassAndDef(self): + unformatted_code = textwrap.dedent("""\ + class Foo: + + def joe(): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + class Foo: + def joe(): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testNoBlankBetweenDefsInClass(self): + unformatted_code = textwrap.dedent('''\ + class TestClass: + def __init__(self): + self.running = False + def run(self): + """Override in subclass""" + def is_running(self): + return self.running + ''') + expected_formatted_code = textwrap.dedent('''\ + class TestClass: + def __init__(self): + self.running = False + + def run(self): + """Override in subclass""" + + def is_running(self): + return self.running + ''') + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSingleWhiteBeforeTrailingComment(self): + unformatted_code = textwrap.dedent("""\ + if a+b: # comment + pass + """) + expected_formatted_code = textwrap.dedent("""\ + if a + b: # comment + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSpaceBetweenEndingCommandAndClosingBracket(self): + unformatted_code = textwrap.dedent("""\ + a = ( + 1, + ) + """) + expected_formatted_code = textwrap.dedent("""\ + a = (1, ) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testContinuedNonOutdentedLine(self): + code = textwrap.dedent("""\ + class eld(d): + if str(geom.geom_type).upper( + ) != self.geom_type and not self.geom_type == 'GEOMETRY': + ror(code='om_type') + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testWrappingPercentExpressions(self): + unformatted_code = textwrap.dedent("""\ + def f(): + if True: + zzzzz = '%s-%s' % (xxxxxxxxxxxxxxxxxxxxxxxxxx + 1, xxxxxxxxxxxxxxxxx.yyy + 1) + zzzzz = '%s-%s'.ww(xxxxxxxxxxxxxxxxxxxxxxxxxx + 1, xxxxxxxxxxxxxxxxx.yyy + 1) + zzzzz = '%s-%s' % (xxxxxxxxxxxxxxxxxxxxxxx + 1, xxxxxxxxxxxxxxxxxxxxx + 1) + zzzzz = '%s-%s'.ww(xxxxxxxxxxxxxxxxxxxxxxx + 1, xxxxxxxxxxxxxxxxxxxxx + 1) + """) + expected_formatted_code = textwrap.dedent("""\ + def f(): + if True: + zzzzz = '%s-%s' % (xxxxxxxxxxxxxxxxxxxxxxxxxx + 1, + xxxxxxxxxxxxxxxxx.yyy + 1) + zzzzz = '%s-%s'.ww(xxxxxxxxxxxxxxxxxxxxxxxxxx + 1, + xxxxxxxxxxxxxxxxx.yyy + 1) + zzzzz = '%s-%s' % (xxxxxxxxxxxxxxxxxxxxxxx + 1, + xxxxxxxxxxxxxxxxxxxxx + 1) + zzzzz = '%s-%s'.ww(xxxxxxxxxxxxxxxxxxxxxxx + 1, + xxxxxxxxxxxxxxxxxxxxx + 1) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testAlignClosingBracketWithVisualIndentation(self): + unformatted_code = textwrap.dedent("""\ + TEST_LIST = ('foo', 'bar', # first comment + 'baz' # second comment + ) + """) + expected_formatted_code = textwrap.dedent("""\ + TEST_LIST = ( + 'foo', + 'bar', # first comment + 'baz' # second comment + ) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + def f(): + + def g(): + while (xxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) == 'bbbbbbb' + ): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def f(): + def g(): + while (xxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa' + and xxxxxxxxxxxxxxxxxxxx( + yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) == 'bbbbbbb'): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testIndentSizeChanging(self): + unformatted_code = textwrap.dedent("""\ + if True: + runtime_mins = (program_end_time - program_start_time).total_seconds() / 60.0 + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + runtime_mins = (program_end_time - + program_start_time).total_seconds() / 60.0 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testHangingIndentCollision(self): + unformatted_code = textwrap.dedent("""\ + if (aaaaaaaaaaaaaa + bbbbbbbbbbbbbbbb == ccccccccccccccccc and xxxxxxxxxxxxx or yyyyyyyyyyyyyyyyy): + pass + elif (xxxxxxxxxxxxxxx(aaaaaaaaaaa, bbbbbbbbbbbbbb, cccccccccccc, dddddddddd=None)): + pass + + + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + for connection in itertools.chain(branch.contact, branch.address, morestuff.andmore.andmore.andmore.andmore.andmore.andmore.andmore): + dosomething(connection) + """) + expected_formatted_code = textwrap.dedent("""\ + if (aaaaaaaaaaaaaa + bbbbbbbbbbbbbbbb == ccccccccccccccccc and xxxxxxxxxxxxx + or yyyyyyyyyyyyyyyyy): + pass + elif (xxxxxxxxxxxxxxx(aaaaaaaaaaa, + bbbbbbbbbbbbbb, + cccccccccccc, + dddddddddd=None)): + pass + + + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + for connection in itertools.chain( + branch.contact, branch.address, + morestuff.andmore.andmore.andmore.andmore.andmore.andmore.andmore): + dosomething(connection) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSplittingBeforeLogicalOperator(self): + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: pep8, split_before_logical_operator: True}')) + unformatted_code = textwrap.dedent("""\ + def foo(): + return bool(update.message.new_chat_member or update.message.left_chat_member or + update.message.new_chat_title or update.message.new_chat_photo or + update.message.delete_chat_photo or update.message.group_chat_created or + update.message.supergroup_chat_created or update.message.channel_chat_created + or update.message.migrate_to_chat_id or update.message.migrate_from_chat_id or + update.message.pinned_message) + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): + return bool( + update.message.new_chat_member or update.message.left_chat_member + or update.message.new_chat_title or update.message.new_chat_photo + or update.message.delete_chat_photo + or update.message.group_chat_created + or update.message.supergroup_chat_created + or update.message.channel_chat_created + or update.message.migrate_to_chat_id + or update.message.migrate_from_chat_id + or update.message.pinned_message) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testContiguousListEndingWithComment(self): + unformatted_code = textwrap.dedent("""\ + if True: + if True: + keys.append(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) # may be unassigned. + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + if True: + keys.append( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) # may be unassigned. + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSplittingBeforeFirstArgument(self): + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: pep8, split_before_first_argument: True}')) + unformatted_code = textwrap.dedent("""\ + a_very_long_function_name(long_argument_name_1=1, long_argument_name_2=2, + long_argument_name_3=3, long_argument_name_4=4) + """) + expected_formatted_code = textwrap.dedent("""\ + a_very_long_function_name( + long_argument_name_1=1, + long_argument_name_2=2, + long_argument_name_3=3, + long_argument_name_4=4) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testSplittingExpressionsInsideSubscripts(self): + unformatted_code = textwrap.dedent("""\ + def foo(): + df = df[(df['campaign_status'] == 'LIVE') & (df['action_status'] == 'LIVE')] + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): + df = df[(df['campaign_status'] == 'LIVE') + & (df['action_status'] == 'LIVE')] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSplitListsAndDictSetMakersIfCommaTerminated(self): + unformatted_code = textwrap.dedent("""\ + DJANGO_TEMPLATES_OPTIONS = {"context_processors": []} + DJANGO_TEMPLATES_OPTIONS = {"context_processors": [],} + x = ["context_processors"] + x = ["context_processors",] + """) + expected_formatted_code = textwrap.dedent("""\ + DJANGO_TEMPLATES_OPTIONS = {"context_processors": []} + DJANGO_TEMPLATES_OPTIONS = { + "context_processors": [], + } + x = ["context_processors"] + x = [ + "context_processors", + ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSplitAroundNamedAssigns(self): + unformatted_code = textwrap.dedent("""\ + class a(): + def a(): return a( + aaaaaaaaaa=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) + """) + expected_formatted_code = textwrap.dedent("""\ + class a(): + def a(): + return a( + aaaaaaaaaa=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testUnaryOperator(self): + unformatted_code = textwrap.dedent("""\ + if not -3 < x < 3: + pass + if -3 < x < 3: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + if not -3 < x < 3: + pass + if -3 < x < 3: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testNoSplitBeforeDictValue(self): + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig('{based_on_style: pep8, ' + 'allow_split_before_dict_value: false, ' + 'coalesce_brackets: true, ' + 'dedent_closing_brackets: true, ' + 'each_dict_entry_on_separate_line: true, ' + 'split_before_logical_operator: true}')) + + unformatted_code = textwrap.dedent("""\ + some_dict = { + 'title': _("I am example data"), + 'description': _("Lorem ipsum dolor met sit amet elit, si vis pacem para bellum " + "elites nihi very long string."), + } + """) + expected_formatted_code = textwrap.dedent("""\ + some_dict = { + 'title': _("I am example data"), + 'description': _( + "Lorem ipsum dolor met sit amet elit, si vis pacem para bellum " + "elites nihi very long string." + ), + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + X = {'a': 1, 'b': 2, 'key': this_is_a_function_call_that_goes_over_the_column_limit_im_pretty_sure()} + """) + expected_formatted_code = textwrap.dedent("""\ + X = { + 'a': 1, + 'b': 2, + 'key': this_is_a_function_call_that_goes_over_the_column_limit_im_pretty_sure() + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + attrs = { + 'category': category, + 'role': forms.ModelChoiceField(label=_("Role"), required=False, queryset=category_roles, initial=selected_role, empty_label=_("No access"),), + } + """) + expected_formatted_code = textwrap.dedent("""\ + attrs = { + 'category': category, + 'role': forms.ModelChoiceField( + label=_("Role"), + required=False, + queryset=category_roles, + initial=selected_role, + empty_label=_("No access"), + ), + } + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + + unformatted_code = textwrap.dedent("""\ + css_class = forms.CharField( + label=_("CSS class"), + required=False, + help_text=_("Optional CSS class used to customize this category appearance from templates."), + ) + """) + expected_formatted_code = textwrap.dedent("""\ + css_class = forms.CharField( + label=_("CSS class"), + required=False, + help_text=_( + "Optional CSS class used to customize this category appearance from templates." + ), + ) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testBitwiseOperandSplitting(self): + unformatted_code = """\ +def _(): + include_values = np.where( + (cdffile['Quality_Flag'][:] >= 5) & ( + cdffile['Day_Night_Flag'][:] == 1) & ( + cdffile['Longitude'][:] >= select_lon - radius) & ( + cdffile['Longitude'][:] <= select_lon + radius) & ( + cdffile['Latitude'][:] >= select_lat - radius) & ( + cdffile['Latitude'][:] <= select_lat + radius)) +""" + expected_code = """\ +def _(): + include_values = np.where( + (cdffile['Quality_Flag'][:] >= 5) & (cdffile['Day_Night_Flag'][:] == 1) + & (cdffile['Longitude'][:] >= select_lon - radius) + & (cdffile['Longitude'][:] <= select_lon + radius) + & (cdffile['Latitude'][:] >= select_lat - radius) + & (cdffile['Latitude'][:] <= select_lat + radius)) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertEqual(expected_code, reformatter.Reformat(uwlines)) + + def testNoBlankLinesOnlyForFirstNestedObject(self): + unformatted_code = '''\ +class Demo: + """ + Demo docs + """ + def foo(self): + """ + foo docs + """ + def bar(self): + """ + bar docs + """ +''' + expected_code = '''\ +class Demo: + """ + Demo docs + """ + def foo(self): + """ + foo docs + """ + + def bar(self): + """ + bar docs + """ +''' + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertEqual(expected_code, reformatter.Reformat(uwlines)) + + def testSplitBeforeArithmeticOperators(self): + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: pep8, split_before_arithmetic_operator: true}')) + + unformatted_code = """\ +def _(): + raise ValueError('This is a long message that ends with an argument: ' + str(42)) +""" + expected_formatted_code = """\ +def _(): + raise ValueError('This is a long message that ends with an argument: ' + + str(42)) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testListSplitting(self): + unformatted_code = """\ +foo([(1,1), (1,1), (1,1), (1,1), (1,1), (1,1), (1,1), + (1,1), (1,1), (1,1), (1,1), (1,1), (1,1), (1,1), + (1,10), (1,11), (1, 10), (1,11), (10,11)]) +""" + expected_code = """\ +foo([(1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), + (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 10), (1, 11), (1, 10), + (1, 11), (10, 11)]) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_code, reformatter.Reformat(uwlines)) + + def testNoBlankLineBeforeNestedFuncOrClass(self): + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: pep8, ' + 'blank_line_before_nested_class_or_def: false}')) + + unformatted_code = '''\ +def normal_function(): + """Return the nested function.""" + + def nested_function(): + """Do nothing just nest within.""" + + @nested(klass) + class nested_class(): + pass + + pass + + return nested_function +''' + expected_formatted_code = '''\ +def normal_function(): + """Return the nested function.""" + def nested_function(): + """Do nothing just nest within.""" + @nested(klass) + class nested_class(): + pass + + pass + + return nested_function +''' + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testParamListIndentationCollision1(self): + unformatted_code = textwrap.dedent("""\ +class _(): + + def __init__(self, title: Optional[str], diffs: Collection[BinaryDiff] = (), charset: Union[Type[AsciiCharset], Type[LineCharset]] = AsciiCharset, preprocess: Callable[[str], str] = identity, + # TODO(somebody): Make this a Literal type. + justify: str = 'rjust'): + self._cs = charset + self._preprocess = preprocess + """) + expected_formatted_code = textwrap.dedent("""\ +class _(): + def __init__( + self, + title: Optional[str], + diffs: Collection[BinaryDiff] = (), + charset: Union[Type[AsciiCharset], + Type[LineCharset]] = AsciiCharset, + preprocess: Callable[[str], str] = identity, + # TODO(somebody): Make this a Literal type. + justify: str = 'rjust'): + self._cs = charset + self._preprocess = preprocess + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testParamListIndentationCollision2(self): + code = textwrap.dedent("""\ + def simple_pass_function_with_an_extremely_long_name_and_some_arguments( + argument0, argument1): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testParamListIndentationCollision3(self): + code = textwrap.dedent("""\ + def func1( + arg1, + arg2, + ) -> None: + pass + + + def func2( + arg1, + arg2, + ): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testTwoWordComparisonOperators(self): + unformatted_code = textwrap.dedent("""\ + _ = (klsdfjdklsfjksdlfjdklsfjdslkfjsdkl is not ksldfjsdklfjdklsfjdklsfjdklsfjdsklfjdklsfj) + _ = (klsdfjdklsfjksdlfjdklsfjdslkfjsdkl not in {ksldfjsdklfjdklsfjdklsfjdklsfjdsklfjdklsfj}) + """) + expected_formatted_code = textwrap.dedent("""\ + _ = (klsdfjdklsfjksdlfjdklsfjdslkfjsdkl + is not ksldfjsdklfjdklsfjdklsfjdklsfjdsklfjdklsfj) + _ = (klsdfjdklsfjksdlfjdklsfjdslkfjsdkl + not in {ksldfjsdklfjdklsfjdklsfjdklsfjdsklfjdklsfj}) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + @unittest.skipUnless(not py3compat.PY3, 'Requires Python 2.7') + def testAsyncAsNonKeyword(self): + # In Python 2, async may be used as a non-keyword identifier. + code = textwrap.dedent("""\ + from util import async + + + class A(object): + def foo(self): + async.run() + + def bar(self): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines, verify=False)) + + def testStableInlinedDictionaryFormatting(self): + unformatted_code = textwrap.dedent("""\ + def _(): + url = "http://{0}/axis-cgi/admin/param.cgi?{1}".format( + value, urllib.urlencode({'action': 'update', 'parameter': value})) + """) + expected_formatted_code = textwrap.dedent("""\ + def _(): + url = "http://{0}/axis-cgi/admin/param.cgi?{1}".format( + value, urllib.urlencode({ + 'action': 'update', + 'parameter': value + })) + """) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + reformatted_code = reformatter.Reformat(uwlines) + self.assertCodeEqual(expected_formatted_code, reformatted_code) + + uwlines = yapf_test_helper.ParseAndUnwrap(reformatted_code) + reformatted_code = reformatter.Reformat(uwlines) + self.assertCodeEqual(expected_formatted_code, reformatted_code) + + +class TestsForSpacesInsideBrackets(yapf_test_helper.YAPFTest): + """Test the SPACE_INSIDE_BRACKETS style option.""" + unformatted_code = textwrap.dedent("""\ + foo() + foo(1) + foo(1,2) + foo((1,)) + foo((1, 2)) + foo((1, 2,)) + foo(bar['baz'][0]) + set1 = {1, 2, 3} + dict1 = {1: 1, foo: 2, 3: bar} + dict2 = { + 1: 1, + foo: 2, + 3: bar, + } + dict3[3][1][get_index(*args,**kwargs)] + dict4[3][1][get_index(**kwargs)] + x = dict5[4](foo(*args)) + a = list1[:] + b = list2[slice_start:] + c = list3[slice_start:slice_end] + d = list4[slice_start:slice_end:] + e = list5[slice_start:slice_end:slice_step] + # Print gets special handling + print(set2) + compound = ((10+3)/(5-2**(6+x))) + string_idx = "mystring"[3] + """) + + def testEnabled(self): + style.SetGlobalStyle( + style.CreateStyleFromConfig('{space_inside_brackets: True}')) + + expected_formatted_code = textwrap.dedent("""\ + foo() + foo( 1 ) + foo( 1, 2 ) + foo( ( 1, ) ) + foo( ( 1, 2 ) ) + foo( ( + 1, + 2, + ) ) + foo( bar[ 'baz' ][ 0 ] ) + set1 = { 1, 2, 3 } + dict1 = { 1: 1, foo: 2, 3: bar } + dict2 = { + 1: 1, + foo: 2, + 3: bar, + } + dict3[ 3 ][ 1 ][ get_index( *args, **kwargs ) ] + dict4[ 3 ][ 1 ][ get_index( **kwargs ) ] + x = dict5[ 4 ]( foo( *args ) ) + a = list1[ : ] + b = list2[ slice_start: ] + c = list3[ slice_start:slice_end ] + d = list4[ slice_start:slice_end: ] + e = list5[ slice_start:slice_end:slice_step ] + # Print gets special handling + print( set2 ) + compound = ( ( 10 + 3 ) / ( 5 - 2**( 6 + x ) ) ) + string_idx = "mystring"[ 3 ] + """) + + uwlines = yapf_test_helper.ParseAndUnwrap(self.unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testDefault(self): + style.SetGlobalStyle(style.CreatePEP8Style()) + + expected_formatted_code = textwrap.dedent("""\ + foo() + foo(1) + foo(1, 2) + foo((1, )) + foo((1, 2)) + foo(( + 1, + 2, + )) + foo(bar['baz'][0]) + set1 = {1, 2, 3} + dict1 = {1: 1, foo: 2, 3: bar} + dict2 = { + 1: 1, + foo: 2, + 3: bar, + } + dict3[3][1][get_index(*args, **kwargs)] + dict4[3][1][get_index(**kwargs)] + x = dict5[4](foo(*args)) + a = list1[:] + b = list2[slice_start:] + c = list3[slice_start:slice_end] + d = list4[slice_start:slice_end:] + e = list5[slice_start:slice_end:slice_step] + # Print gets special handling + print(set2) + compound = ((10 + 3) / (5 - 2**(6 + x))) + string_idx = "mystring"[3] + """) + + uwlines = yapf_test_helper.ParseAndUnwrap(self.unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6') + def testAwait(self): + style.SetGlobalStyle( + style.CreateStyleFromConfig('{space_inside_brackets: True}')) + unformatted_code = textwrap.dedent("""\ + import asyncio + import time + + @print_args + async def slow_operation(): + await asyncio.sleep(1) + # print("Slow operation {} complete".format(n)) + async def main(): + start = time.time() + if (await get_html()): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + import asyncio + import time + + + @print_args + async def slow_operation(): + await asyncio.sleep( 1 ) + + # print("Slow operation {} complete".format(n)) + async def main(): + start = time.time() + if ( await get_html() ): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + +class TestsForSpacesAroundSubscriptColon(yapf_test_helper.YAPFTest): + """Test the SPACES_AROUND_SUBSCRIPT_COLON style option.""" + unformatted_code = textwrap.dedent("""\ + a = list1[ : ] + b = list2[ slice_start: ] + c = list3[ slice_start:slice_end ] + d = list4[ slice_start:slice_end: ] + e = list5[ slice_start:slice_end:slice_step ] + a1 = list1[ : ] + b1 = list2[ 1: ] + c1 = list3[ 1:20 ] + d1 = list4[ 1:20: ] + e1 = list5[ 1:20:3 ] + """) + + def testEnabled(self): + style.SetGlobalStyle( + style.CreateStyleFromConfig('{spaces_around_subscript_colon: True}')) + expected_formatted_code = textwrap.dedent("""\ + a = list1[:] + b = list2[slice_start :] + c = list3[slice_start : slice_end] + d = list4[slice_start : slice_end :] + e = list5[slice_start : slice_end : slice_step] + a1 = list1[:] + b1 = list2[1 :] + c1 = list3[1 : 20] + d1 = list4[1 : 20 :] + e1 = list5[1 : 20 : 3] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(self.unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testWithSpaceInsideBrackets(self): + style.SetGlobalStyle( + style.CreateStyleFromConfig('{' + 'spaces_around_subscript_colon: true, ' + 'space_inside_brackets: true,' + '}')) + expected_formatted_code = textwrap.dedent("""\ + a = list1[ : ] + b = list2[ slice_start : ] + c = list3[ slice_start : slice_end ] + d = list4[ slice_start : slice_end : ] + e = list5[ slice_start : slice_end : slice_step ] + a1 = list1[ : ] + b1 = list2[ 1 : ] + c1 = list3[ 1 : 20 ] + d1 = list4[ 1 : 20 : ] + e1 = list5[ 1 : 20 : 3 ] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(self.unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testDefault(self): + style.SetGlobalStyle(style.CreatePEP8Style()) + expected_formatted_code = textwrap.dedent("""\ + a = list1[:] + b = list2[slice_start:] + c = list3[slice_start:slice_end] + d = list4[slice_start:slice_end:] + e = list5[slice_start:slice_end:slice_step] + a1 = list1[:] + b1 = list2[1:] + c1 = list3[1:20] + d1 = list4[1:20:] + e1 = list5[1:20:3] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(self.unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_python3_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_python3_test.py new file mode 100644 index 00000000..d06e4062 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_python3_test.py @@ -0,0 +1,471 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Python 3 tests for yapf.reformatter.""" + +import sys +import textwrap +import unittest + +from yapf.yapflib import py3compat +from yapf.yapflib import reformatter +from yapf.yapflib import style + +from yapftests import yapf_test_helper + + +@unittest.skipUnless(py3compat.PY3, 'Requires Python 3') +class TestsForPython3Code(yapf_test_helper.YAPFTest): + """Test a few constructs that are new Python 3 syntax.""" + + @classmethod + def setUpClass(cls): # pylint: disable=g-missing-super-call + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testTypedNames(self): + unformatted_code = textwrap.dedent("""\ + def x(aaaaaaaaaaaaaaa:int,bbbbbbbbbbbbbbbb:str,ccccccccccccccc:dict,eeeeeeeeeeeeee:set={1, 2, 3})->bool: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def x(aaaaaaaaaaaaaaa: int, + bbbbbbbbbbbbbbbb: str, + ccccccccccccccc: dict, + eeeeeeeeeeeeee: set = {1, 2, 3}) -> bool: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testTypedNameWithLongNamedArg(self): + unformatted_code = textwrap.dedent("""\ + def func(arg=long_function_call_that_pushes_the_line_over_eighty_characters()) -> ReturnType: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def func(arg=long_function_call_that_pushes_the_line_over_eighty_characters() + ) -> ReturnType: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testKeywordOnlyArgSpecifier(self): + unformatted_code = textwrap.dedent("""\ + def foo(a, *, kw): + return a+kw + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(a, *, kw): + return a + kw + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6') + def testPEP448ParameterExpansion(self): + unformatted_code = textwrap.dedent("""\ + { ** x } + { **{} } + { **{ **x }, **x } + {'a': 1, **kw , 'b':3, **kw2 } + """) + expected_formatted_code = textwrap.dedent("""\ + {**x} + {**{}} + {**{**x}, **x} + {'a': 1, **kw, 'b': 3, **kw2} + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testAnnotations(self): + unformatted_code = textwrap.dedent("""\ + def foo(a: list, b: "bar") -> dict: + return a+b + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(a: list, b: "bar") -> dict: + return a + b + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testExecAsNonKeyword(self): + unformatted_code = 'methods.exec( sys.modules[name])\n' + expected_formatted_code = 'methods.exec(sys.modules[name])\n' + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testAsyncFunctions(self): + if sys.version_info[1] < 5: + return + code = textwrap.dedent("""\ + import asyncio + import time + + + @print_args + async def slow_operation(): + await asyncio.sleep(1) + # print("Slow operation {} complete".format(n)) + + + async def main(): + start = time.time() + if (await get_html()): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines, verify=False)) + + def testNoSpacesAroundPowerOperator(self): + unformatted_code = textwrap.dedent("""\ + a**b + """) + expected_formatted_code = textwrap.dedent("""\ + a ** b + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: pep8, SPACES_AROUND_POWER_OPERATOR: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testSpacesAroundDefaultOrNamedAssign(self): + unformatted_code = textwrap.dedent("""\ + f(a=5) + """) + expected_formatted_code = textwrap.dedent("""\ + f(a = 5) + """) + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: pep8, ' + 'SPACES_AROUND_DEFAULT_OR_NAMED_ASSIGN: True}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testTypeHint(self): + unformatted_code = textwrap.dedent("""\ + def foo(x: int=42): + pass + + + def foo2(x: 'int' =42): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(x: int = 42): + pass + + + def foo2(x: 'int' = 42): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testMatrixMultiplication(self): + unformatted_code = textwrap.dedent("""\ + a=b@c + """) + expected_formatted_code = textwrap.dedent("""\ + a = b @ c + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testNoneKeyword(self): + code = """\ +None.__ne__() +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testAsyncWithPrecedingComment(self): + if sys.version_info[1] < 5: + return + unformatted_code = textwrap.dedent("""\ + import asyncio + + # Comment + async def bar(): + pass + + async def foo(): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + import asyncio + + + # Comment + async def bar(): + pass + + + async def foo(): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testAsyncFunctionsNested(self): + if sys.version_info[1] < 5: + return + code = textwrap.dedent("""\ + async def outer(): + async def inner(): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testKeepTypesIntact(self): + if sys.version_info[1] < 5: + return + unformatted_code = textwrap.dedent("""\ + def _ReduceAbstractContainers( + self, *args: Optional[automation_converter.PyiCollectionAbc]) -> List[ + automation_converter.PyiCollectionAbc]: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def _ReduceAbstractContainers( + self, *args: Optional[automation_converter.PyiCollectionAbc] + ) -> List[automation_converter.PyiCollectionAbc]: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testContinuationIndentWithAsync(self): + if sys.version_info[1] < 5: + return + unformatted_code = textwrap.dedent("""\ + async def start_websocket(): + async with session.ws_connect( + r"ws://a_really_long_long_long_long_long_long_url") as ws: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + async def start_websocket(): + async with session.ws_connect( + r"ws://a_really_long_long_long_long_long_long_url") as ws: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testSplittingArguments(self): + if sys.version_info[1] < 5: + return + + unformatted_code = """\ +async def open_file(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None): + pass + +async def run_sync_in_worker_thread(sync_fn, *args, cancellable=False, limiter=None): + pass + +def open_file(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None): + pass + +def run_sync_in_worker_thread(sync_fn, *args, cancellable=False, limiter=None): + pass +""" + expected_formatted_code = """\ +async def open_file( + file, + mode='r', + buffering=-1, + encoding=None, + errors=None, + newline=None, + closefd=True, + opener=None +): + pass + + +async def run_sync_in_worker_thread( + sync_fn, *args, cancellable=False, limiter=None +): + pass + + +def open_file( + file, + mode='r', + buffering=-1, + encoding=None, + errors=None, + newline=None, + closefd=True, + opener=None +): + pass + + +def run_sync_in_worker_thread(sync_fn, *args, cancellable=False, limiter=None): + pass +""" + + try: + style.SetGlobalStyle( + style.CreateStyleFromConfig( + '{based_on_style: pep8, ' + 'dedent_closing_brackets: true, ' + 'coalesce_brackets: false, ' + 'space_between_ending_comma_and_closing_bracket: false, ' + 'split_arguments_when_comma_terminated: true, ' + 'split_before_first_argument: true}')) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testDictUnpacking(self): + if sys.version_info[1] < 5: + return + unformatted_code = """\ +class Foo: + def foo(self): + foofoofoofoofoofoofoofoo('foofoofoofoofoo', { + + 'foo': 'foo', + + **foofoofoo + }) +""" + expected_formatted_code = """\ +class Foo: + def foo(self): + foofoofoofoofoofoofoofoo('foofoofoofoofoo', { + 'foo': 'foo', + **foofoofoo + }) +""" + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testMultilineFormatString(self): + if sys.version_info[1] < 6: + return + code = """\ +# yapf: disable +(f''' + ''') +# yapf: enable +""" + # https://github.com/google/yapf/issues/513 + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testEllipses(self): + if sys.version_info[1] < 6: + return + code = """\ +def dirichlet(x12345678901234567890123456789012345678901234567890=...) -> None: + return +""" + # https://github.com/google/yapf/issues/533 + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testFunctionTypedReturnNextLine(self): + code = """\ +def _GenerateStatsEntries( + process_id: Text, + timestamp: Optional[ffffffff.FFFFFFFFFFF] = None +) -> Sequence[ssssssssssss.SSSSSSSSSSSSSSS]: + pass +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testFunctionTypedReturnSameLine(self): + code = """\ +def rrrrrrrrrrrrrrrrrrrrrr( + ccccccccccccccccccccccc: Tuple[Text, Text]) -> List[Tuple[Text, Text]]: + pass +""" + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testAsyncForElseNotIndentedInsideBody(self): + if sys.version_info[1] < 5: + return + code = textwrap.dedent("""\ + async def fn(): + async for message in websocket: + for i in range(10): + pass + else: + pass + else: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testForElseInAsyncNotMixedWithAsyncFor(self): + if sys.version_info[1] < 5: + return + code = textwrap.dedent("""\ + async def fn(): + for i in range(10): + pass + else: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self.assertCodeEqual(code, reformatter.Reformat(uwlines)) + + def testParameterListIndentationConflicts(self): + unformatted_code = textwrap.dedent("""\ + def raw_message( # pylint: disable=too-many-arguments + self, text, user_id=1000, chat_type='private', forward_date=None, forward_from=None): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def raw_message( # pylint: disable=too-many-arguments + self, + text, + user_id=1000, + chat_type='private', + forward_date=None, + forward_from=None): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_style_config_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_style_config_test.py new file mode 100644 index 00000000..d77c1970 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_style_config_test.py @@ -0,0 +1,198 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Style config tests for yapf.reformatter.""" + +import textwrap +import unittest + +from yapf.yapflib import reformatter +from yapf.yapflib import style + +from yapftests import yapf_test_helper + + +class TestsForStyleConfig(yapf_test_helper.YAPFTest): + + def setUp(self): + self.current_style = style.DEFAULT_STYLE + + def testSetGlobalStyle(self): + try: + style.SetGlobalStyle(style.CreateYapfStyle()) + unformatted_code = textwrap.dedent(u"""\ + for i in range(5): + print('bar') + """) + expected_formatted_code = textwrap.dedent(u"""\ + for i in range(5): + print('bar') + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + style.DEFAULT_STYLE = self.current_style + + unformatted_code = textwrap.dedent(u"""\ + for i in range(5): + print('bar') + """) + expected_formatted_code = textwrap.dedent(u"""\ + for i in range(5): + print('bar') + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, reformatter.Reformat(uwlines)) + + def testOperatorNoSpaceStyle(self): + try: + sympy_style = style.CreatePEP8Style() + sympy_style['NO_SPACES_AROUND_SELECTED_BINARY_OPERATORS'] = \ + style._StringSetConverter('*,/') + style.SetGlobalStyle(sympy_style) + unformatted_code = textwrap.dedent("""\ + a = 1+2 * 3 - 4 / 5 + b = '0' * 1 + """) + expected_formatted_code = textwrap.dedent("""\ + a = 1 + 2*3 - 4/5 + b = '0'*1 + """) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + style.DEFAULT_STYLE = self.current_style + + def testOperatorPrecedenceStyle(self): + try: + pep8_with_precedence = style.CreatePEP8Style() + pep8_with_precedence['ARITHMETIC_PRECEDENCE_INDICATION'] = True + style.SetGlobalStyle(pep8_with_precedence) + unformatted_code = textwrap.dedent("""\ + 1+2 + (1 + 2) * (3 - (4 / 5)) + a = 1 * 2 + 3 / 4 + b = 1 / 2 - 3 * 4 + c = (1 + 2) * (3 - 4) + d = (1 - 2) / (3 + 4) + e = 1 * 2 - 3 + f = 1 + 2 + 3 + 4 + g = 1 * 2 * 3 * 4 + h = 1 + 2 - 3 + 4 + i = 1 * 2 / 3 * 4 + j = (1 * 2 - 3) + 4 + k = (1 * 2 * 3) + (4 * 5 * 6 * 7 * 8) + """) + expected_formatted_code = textwrap.dedent("""\ + 1 + 2 + (1+2) * (3 - (4/5)) + a = 1*2 + 3/4 + b = 1/2 - 3*4 + c = (1+2) * (3-4) + d = (1-2) / (3+4) + e = 1*2 - 3 + f = 1 + 2 + 3 + 4 + g = 1 * 2 * 3 * 4 + h = 1 + 2 - 3 + 4 + i = 1 * 2 / 3 * 4 + j = (1*2 - 3) + 4 + k = (1*2*3) + (4*5*6*7*8) + """) + + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + style.DEFAULT_STYLE = self.current_style + + def testNoSplitBeforeFirstArgumentStyle1(self): + try: + pep8_no_split_before_first = style.CreatePEP8Style() + pep8_no_split_before_first['SPLIT_BEFORE_FIRST_ARGUMENT'] = False + pep8_no_split_before_first['SPLIT_BEFORE_NAMED_ASSIGNS'] = False + style.SetGlobalStyle(pep8_no_split_before_first) + formatted_code = textwrap.dedent("""\ + # Example from in-code MustSplit comments + foo = outer_function_call(fitting_inner_function_call(inner_arg1, inner_arg2), + outer_arg1, outer_arg2) + + foo = outer_function_call( + not_fitting_inner_function_call(inner_arg1, inner_arg2), outer_arg1, + outer_arg2) + + # Examples Issue#424 + a_super_long_version_of_print(argument1, argument2, argument3, argument4, + argument5, argument6, argument7) + + CREDS_FILE = os.path.join(os.path.expanduser('~'), + 'apis/super-secret-admin-creds.json') + + # Examples Issue#556 + i_take_a_lot_of_params(arg1, param1=very_long_expression1(), + param2=very_long_expression2(), + param3=very_long_expression3(), + param4=very_long_expression4()) + + # Examples Issue#590 + plt.plot(numpy.linspace(0, 1, 10), numpy.linspace(0, 1, 10), marker="x", + color="r") + + plt.plot(veryverylongvariablename, veryverylongvariablename, marker="x", + color="r") + """) + uwlines = yapf_test_helper.ParseAndUnwrap(formatted_code) + self.assertCodeEqual(formatted_code, reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + style.DEFAULT_STYLE = self.current_style + + def testNoSplitBeforeFirstArgumentStyle2(self): + try: + pep8_no_split_before_first = style.CreatePEP8Style() + pep8_no_split_before_first['SPLIT_BEFORE_FIRST_ARGUMENT'] = False + pep8_no_split_before_first['SPLIT_BEFORE_NAMED_ASSIGNS'] = True + style.SetGlobalStyle(pep8_no_split_before_first) + formatted_code = textwrap.dedent("""\ + # Examples Issue#556 + i_take_a_lot_of_params(arg1, + param1=very_long_expression1(), + param2=very_long_expression2(), + param3=very_long_expression3(), + param4=very_long_expression4()) + + # Examples Issue#590 + plt.plot(numpy.linspace(0, 1, 10), + numpy.linspace(0, 1, 10), + marker="x", + color="r") + + plt.plot(veryverylongvariablename, + veryverylongvariablename, + marker="x", + color="r") + """) + uwlines = yapf_test_helper.ParseAndUnwrap(formatted_code) + self.assertCodeEqual(formatted_code, reformatter.Reformat(uwlines)) + finally: + style.SetGlobalStyle(style.CreatePEP8Style()) + style.DEFAULT_STYLE = self.current_style + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_verify_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_verify_test.py new file mode 100644 index 00000000..1b3d5b08 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/reformatter_verify_test.py @@ -0,0 +1,108 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.reformatter.""" + +import textwrap +import unittest + +from yapf.yapflib import py3compat +from yapf.yapflib import reformatter +from yapf.yapflib import style +from yapf.yapflib import verifier + +from yapftests import yapf_test_helper + + +@unittest.skipIf(py3compat.PY3, 'Requires Python 2') +class TestVerifyNoVerify(yapf_test_helper.YAPFTest): + + @classmethod + def setUpClass(cls): + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testVerifyException(self): + unformatted_code = textwrap.dedent("""\ + class ABC(metaclass=type): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + with self.assertRaises(verifier.InternalError): + reformatter.Reformat(uwlines, verify=True) + reformatter.Reformat(uwlines) # verify should be False by default. + + def testNoVerify(self): + unformatted_code = textwrap.dedent("""\ + class ABC(metaclass=type): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + class ABC(metaclass=type): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines, verify=False)) + + def testVerifyFutureImport(self): + unformatted_code = textwrap.dedent("""\ + from __future__ import print_function + + def call_my_function(the_function): + the_function("hi") + + if __name__ == "__main__": + call_my_function(print) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + with self.assertRaises(verifier.InternalError): + reformatter.Reformat(uwlines, verify=True) + + expected_formatted_code = textwrap.dedent("""\ + from __future__ import print_function + + + def call_my_function(the_function): + the_function("hi") + + + if __name__ == "__main__": + call_my_function(print) + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines, verify=False)) + + def testContinuationLineShouldBeDistinguished(self): + unformatted_code = textwrap.dedent("""\ + class Foo(object): + + def bar(self): + if self.solo_generator_that_is_long is None and len( + self.generators + self.next_batch) == 1: + pass + """) + expected_formatted_code = textwrap.dedent("""\ + class Foo(object): + def bar(self): + if self.solo_generator_that_is_long is None and len( + self.generators + self.next_batch) == 1: + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(unformatted_code) + self.assertCodeEqual(expected_formatted_code, + reformatter.Reformat(uwlines, verify=False)) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/split_penalty_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/split_penalty_test.py new file mode 100644 index 00000000..4d551291 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/split_penalty_test.py @@ -0,0 +1,266 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.split_penalty.""" + +import sys +import textwrap +import unittest + +from lib2to3 import pytree + +from yapf.yapflib import pytree_utils +from yapf.yapflib import pytree_visitor +from yapf.yapflib import split_penalty +from yapf.yapflib import style + +from yapftests import yapf_test_helper + +UNBREAKABLE = split_penalty.UNBREAKABLE +VERY_STRONGLY_CONNECTED = split_penalty.VERY_STRONGLY_CONNECTED +DOTTED_NAME = split_penalty.DOTTED_NAME +STRONGLY_CONNECTED = split_penalty.STRONGLY_CONNECTED + + +class SplitPenaltyTest(yapf_test_helper.YAPFTest): + + @classmethod + def setUpClass(cls): + style.SetGlobalStyle(style.CreateYapfStyle()) + + def _ParseAndComputePenalties(self, code, dumptree=False): + """Parses the code and computes split penalties. + + Arguments: + code: code to parse as a string + dumptree: if True, the parsed pytree (after penalty assignment) is dumped + to stderr. Useful for debugging. + + Returns: + Parse tree. + """ + tree = pytree_utils.ParseCodeToTree(code) + split_penalty.ComputeSplitPenalties(tree) + if dumptree: + pytree_visitor.DumpPyTree(tree, target_stream=sys.stderr) + return tree + + def _CheckPenalties(self, tree, list_of_expected): + """Check that the tokens in the tree have the correct penalties. + + Args: + tree: the pytree. + list_of_expected: list of (name, penalty) pairs. Non-semantic tokens are + filtered out from the expected values. + """ + + def FlattenRec(tree): + if pytree_utils.NodeName(tree) in pytree_utils.NONSEMANTIC_TOKENS: + return [] + if isinstance(tree, pytree.Leaf): + return [(tree.value, + pytree_utils.GetNodeAnnotation( + tree, pytree_utils.Annotation.SPLIT_PENALTY))] + nodes = [] + for node in tree.children: + nodes += FlattenRec(node) + return nodes + + self.assertEqual(list_of_expected, FlattenRec(tree)) + + def testUnbreakable(self): + # Test function definitions. + code = textwrap.dedent(r""" + def foo(x): + pass + """) + tree = self._ParseAndComputePenalties(code) + self._CheckPenalties(tree, [ + ('def', None), + ('foo', UNBREAKABLE), + ('(', UNBREAKABLE), + ('x', None), + (')', STRONGLY_CONNECTED), + (':', UNBREAKABLE), + ('pass', None), + ]) + + # Test function definition with trailing comment. + code = textwrap.dedent(r""" + def foo(x): # trailing comment + pass + """) + tree = self._ParseAndComputePenalties(code) + self._CheckPenalties(tree, [ + ('def', None), + ('foo', UNBREAKABLE), + ('(', UNBREAKABLE), + ('x', None), + (')', STRONGLY_CONNECTED), + (':', UNBREAKABLE), + ('pass', None), + ]) + + # Test class definitions. + code = textwrap.dedent(r""" + class A: + pass + class B(A): + pass + """) + tree = self._ParseAndComputePenalties(code) + self._CheckPenalties(tree, [ + ('class', None), + ('A', UNBREAKABLE), + (':', UNBREAKABLE), + ('pass', None), + ('class', None), + ('B', UNBREAKABLE), + ('(', UNBREAKABLE), + ('A', None), + (')', None), + (':', UNBREAKABLE), + ('pass', None), + ]) + + # Test lambda definitions. + code = textwrap.dedent(r""" + lambda a, b: None + """) + tree = self._ParseAndComputePenalties(code) + self._CheckPenalties(tree, [ + ('lambda', None), + ('a', VERY_STRONGLY_CONNECTED), + (',', VERY_STRONGLY_CONNECTED), + ('b', VERY_STRONGLY_CONNECTED), + (':', VERY_STRONGLY_CONNECTED), + ('None', VERY_STRONGLY_CONNECTED), + ]) + + # Test dotted names. + code = textwrap.dedent(r""" + import a.b.c + """) + tree = self._ParseAndComputePenalties(code) + self._CheckPenalties(tree, [ + ('import', None), + ('a', None), + ('.', UNBREAKABLE), + ('b', UNBREAKABLE), + ('.', UNBREAKABLE), + ('c', UNBREAKABLE), + ]) + + def testStronglyConnected(self): + # Test dictionary keys. + code = textwrap.dedent(r""" + a = { + 'x': 42, + y(lambda a: 23): 37, + } + """) + tree = self._ParseAndComputePenalties(code) + self._CheckPenalties(tree, [ + ('a', None), + ('=', None), + ('{', None), + ("'x'", None), + (':', STRONGLY_CONNECTED), + ('42', None), + (',', None), + ('y', None), + ('(', UNBREAKABLE), + ('lambda', STRONGLY_CONNECTED), + ('a', VERY_STRONGLY_CONNECTED), + (':', VERY_STRONGLY_CONNECTED), + ('23', VERY_STRONGLY_CONNECTED), + (')', VERY_STRONGLY_CONNECTED), + (':', STRONGLY_CONNECTED), + ('37', None), + (',', None), + ('}', None), + ]) + + # Test list comprehension. + code = textwrap.dedent(r""" + [a for a in foo if a.x == 37] + """) + tree = self._ParseAndComputePenalties(code) + self._CheckPenalties(tree, [ + ('[', None), + ('a', None), + ('for', 0), + ('a', STRONGLY_CONNECTED), + ('in', STRONGLY_CONNECTED), + ('foo', STRONGLY_CONNECTED), + ('if', 0), + ('a', STRONGLY_CONNECTED), + ('.', VERY_STRONGLY_CONNECTED), + ('x', DOTTED_NAME), + ('==', STRONGLY_CONNECTED), + ('37', STRONGLY_CONNECTED), + (']', None), + ]) + + def testFuncCalls(self): + code = 'foo(1, 2, 3)\n' + tree = self._ParseAndComputePenalties(code) + self._CheckPenalties(tree, [ + ('foo', None), + ('(', UNBREAKABLE), + ('1', None), + (',', UNBREAKABLE), + ('2', None), + (',', UNBREAKABLE), + ('3', None), + (')', VERY_STRONGLY_CONNECTED), + ]) + + # Now a method call, which has more than one trailer + code = 'foo.bar.baz(1, 2, 3)\n' + tree = self._ParseAndComputePenalties(code) + self._CheckPenalties(tree, [ + ('foo', None), + ('.', VERY_STRONGLY_CONNECTED), + ('bar', DOTTED_NAME), + ('.', VERY_STRONGLY_CONNECTED), + ('baz', DOTTED_NAME), + ('(', STRONGLY_CONNECTED), + ('1', None), + (',', UNBREAKABLE), + ('2', None), + (',', UNBREAKABLE), + ('3', None), + (')', VERY_STRONGLY_CONNECTED), + ]) + + # Test single generator argument. + code = 'max(i for i in xrange(10))\n' + tree = self._ParseAndComputePenalties(code) + self._CheckPenalties(tree, [ + ('max', None), + ('(', UNBREAKABLE), + ('i', 0), + ('for', 0), + ('i', STRONGLY_CONNECTED), + ('in', STRONGLY_CONNECTED), + ('xrange', STRONGLY_CONNECTED), + ('(', UNBREAKABLE), + ('10', STRONGLY_CONNECTED), + (')', VERY_STRONGLY_CONNECTED), + (')', VERY_STRONGLY_CONNECTED), + ]) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/style_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/style_test.py new file mode 100644 index 00000000..2fd3f2d0 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/style_test.py @@ -0,0 +1,336 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.style.""" + +import os +import shutil +import tempfile +import textwrap +import unittest + +from yapf.yapflib import style + +from yapftests import utils + + +class UtilsTest(unittest.TestCase): + + def testContinuationAlignStyleStringConverter(self): + for cont_align_space in ('', 'space', '"space"', '\'space\''): + self.assertEqual( + style._ContinuationAlignStyleStringConverter(cont_align_space), + 'SPACE') + for cont_align_fixed in ('fixed', '"fixed"', '\'fixed\''): + self.assertEqual( + style._ContinuationAlignStyleStringConverter(cont_align_fixed), + 'FIXED') + for cont_align_valignright in ( + 'valign-right', + '"valign-right"', + '\'valign-right\'', + 'valign_right', + '"valign_right"', + '\'valign_right\'', + ): + self.assertEqual( + style._ContinuationAlignStyleStringConverter(cont_align_valignright), + 'VALIGN-RIGHT') + with self.assertRaises(ValueError) as ctx: + style._ContinuationAlignStyleStringConverter('blahblah') + self.assertIn("unknown continuation align style: 'blahblah'", + str(ctx.exception)) + + def testStringListConverter(self): + self.assertEqual(style._StringListConverter('foo, bar'), ['foo', 'bar']) + self.assertEqual(style._StringListConverter('foo,bar'), ['foo', 'bar']) + self.assertEqual(style._StringListConverter(' foo'), ['foo']) + self.assertEqual( + style._StringListConverter('joe ,foo, bar'), ['joe', 'foo', 'bar']) + + def testBoolConverter(self): + self.assertEqual(style._BoolConverter('true'), True) + self.assertEqual(style._BoolConverter('1'), True) + self.assertEqual(style._BoolConverter('false'), False) + self.assertEqual(style._BoolConverter('0'), False) + + def testIntListConverter(self): + self.assertEqual(style._IntListConverter('1, 2, 3'), [1, 2, 3]) + self.assertEqual(style._IntListConverter('[ 1, 2, 3 ]'), [1, 2, 3]) + self.assertEqual(style._IntListConverter('[ 1, 2, 3, ]'), [1, 2, 3]) + + def testIntOrIntListConverter(self): + self.assertEqual(style._IntOrIntListConverter('10'), 10) + self.assertEqual(style._IntOrIntListConverter('1, 2, 3'), [1, 2, 3]) + + +def _LooksLikeGoogleStyle(cfg): + return cfg['COLUMN_LIMIT'] == 80 and cfg['SPLIT_COMPLEX_COMPREHENSION'] + + +def _LooksLikePEP8Style(cfg): + return cfg['COLUMN_LIMIT'] == 79 + + +def _LooksLikeFacebookStyle(cfg): + return cfg['DEDENT_CLOSING_BRACKETS'] + + +def _LooksLikeYapfStyle(cfg): + return cfg['SPLIT_BEFORE_DOT'] + + +class PredefinedStylesByNameTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): # pylint: disable=g-missing-super-call + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testDefault(self): + # default is PEP8 + cfg = style.CreateStyleFromConfig(None) + self.assertTrue(_LooksLikePEP8Style(cfg)) + + def testPEP8ByName(self): + for pep8_name in ('PEP8', 'pep8', 'Pep8'): + cfg = style.CreateStyleFromConfig(pep8_name) + self.assertTrue(_LooksLikePEP8Style(cfg)) + + def testGoogleByName(self): + for google_name in ('google', 'Google', 'GOOGLE'): + cfg = style.CreateStyleFromConfig(google_name) + self.assertTrue(_LooksLikeGoogleStyle(cfg)) + + def testYapfByName(self): + for yapf_name in ('yapf', 'YAPF'): + cfg = style.CreateStyleFromConfig(yapf_name) + self.assertTrue(_LooksLikeYapfStyle(cfg)) + + def testFacebookByName(self): + for fb_name in ('facebook', 'FACEBOOK', 'Facebook'): + cfg = style.CreateStyleFromConfig(fb_name) + self.assertTrue(_LooksLikeFacebookStyle(cfg)) + + +class StyleFromFileTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): # pylint: disable=g-missing-super-call + cls.test_tmpdir = tempfile.mkdtemp() + style.SetGlobalStyle(style.CreatePEP8Style()) + + @classmethod + def tearDownClass(cls): # pylint: disable=g-missing-super-call + shutil.rmtree(cls.test_tmpdir) + + def testDefaultBasedOnStyle(self): + cfg = textwrap.dedent(u'''\ + [style] + continuation_indent_width = 20 + ''') + with utils.TempFileContents(self.test_tmpdir, cfg) as filepath: + cfg = style.CreateStyleFromConfig(filepath) + self.assertTrue(_LooksLikePEP8Style(cfg)) + self.assertEqual(cfg['CONTINUATION_INDENT_WIDTH'], 20) + + def testDefaultBasedOnPEP8Style(self): + cfg = textwrap.dedent(u'''\ + [style] + based_on_style = pep8 + continuation_indent_width = 40 + ''') + with utils.TempFileContents(self.test_tmpdir, cfg) as filepath: + cfg = style.CreateStyleFromConfig(filepath) + self.assertTrue(_LooksLikePEP8Style(cfg)) + self.assertEqual(cfg['CONTINUATION_INDENT_WIDTH'], 40) + + def testDefaultBasedOnGoogleStyle(self): + cfg = textwrap.dedent(u'''\ + [style] + based_on_style = google + continuation_indent_width = 20 + ''') + with utils.TempFileContents(self.test_tmpdir, cfg) as filepath: + cfg = style.CreateStyleFromConfig(filepath) + self.assertTrue(_LooksLikeGoogleStyle(cfg)) + self.assertEqual(cfg['CONTINUATION_INDENT_WIDTH'], 20) + + def testDefaultBasedOnFacebookStyle(self): + cfg = textwrap.dedent(u'''\ + [style] + based_on_style = facebook + continuation_indent_width = 20 + ''') + with utils.TempFileContents(self.test_tmpdir, cfg) as filepath: + cfg = style.CreateStyleFromConfig(filepath) + self.assertTrue(_LooksLikeFacebookStyle(cfg)) + self.assertEqual(cfg['CONTINUATION_INDENT_WIDTH'], 20) + + def testBoolOptionValue(self): + cfg = textwrap.dedent(u'''\ + [style] + based_on_style = pep8 + SPLIT_BEFORE_NAMED_ASSIGNS=False + split_before_logical_operator = true + ''') + with utils.TempFileContents(self.test_tmpdir, cfg) as filepath: + cfg = style.CreateStyleFromConfig(filepath) + self.assertTrue(_LooksLikePEP8Style(cfg)) + self.assertEqual(cfg['SPLIT_BEFORE_NAMED_ASSIGNS'], False) + self.assertEqual(cfg['SPLIT_BEFORE_LOGICAL_OPERATOR'], True) + + def testStringListOptionValue(self): + cfg = textwrap.dedent(u'''\ + [style] + based_on_style = pep8 + I18N_FUNCTION_CALL = N_, V_, T_ + ''') + with utils.TempFileContents(self.test_tmpdir, cfg) as filepath: + cfg = style.CreateStyleFromConfig(filepath) + self.assertTrue(_LooksLikePEP8Style(cfg)) + self.assertEqual(cfg['I18N_FUNCTION_CALL'], ['N_', 'V_', 'T_']) + + def testErrorNoStyleFile(self): + with self.assertRaisesRegexp(style.StyleConfigError, + 'is not a valid style or file path'): + style.CreateStyleFromConfig('/8822/xyznosuchfile') + + def testErrorNoStyleSection(self): + cfg = textwrap.dedent(u'''\ + [s] + indent_width=2 + ''') + with utils.TempFileContents(self.test_tmpdir, cfg) as filepath: + with self.assertRaisesRegexp(style.StyleConfigError, + 'Unable to find section'): + style.CreateStyleFromConfig(filepath) + + def testErrorUnknownStyleOption(self): + cfg = textwrap.dedent(u'''\ + [style] + indent_width=2 + hummus=2 + ''') + with utils.TempFileContents(self.test_tmpdir, cfg) as filepath: + with self.assertRaisesRegexp(style.StyleConfigError, + 'Unknown style option'): + style.CreateStyleFromConfig(filepath) + + def testPyprojectTomlNoYapfSection(self): + try: + import toml + except ImportError: + return + + filepath = os.path.join(self.test_tmpdir, 'pyproject.toml') + _ = open(filepath, 'w') + with self.assertRaisesRegexp(style.StyleConfigError, + 'Unable to find section'): + style.CreateStyleFromConfig(filepath) + + def testPyprojectTomlParseYapfSection(self): + try: + import toml + except ImportError: + return + + cfg = textwrap.dedent(u'''\ + [tool.yapf] + based_on_style = "pep8" + continuation_indent_width = 40 + ''') + filepath = os.path.join(self.test_tmpdir, 'pyproject.toml') + with open(filepath, 'w') as f: + f.write(cfg) + cfg = style.CreateStyleFromConfig(filepath) + self.assertTrue(_LooksLikePEP8Style(cfg)) + self.assertEqual(cfg['CONTINUATION_INDENT_WIDTH'], 40) + + +class StyleFromDict(unittest.TestCase): + + @classmethod + def setUpClass(cls): # pylint: disable=g-missing-super-call + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testDefaultBasedOnStyle(self): + config_dict = { + 'based_on_style': 'pep8', + 'indent_width': 2, + 'blank_line_before_nested_class_or_def': True + } + cfg = style.CreateStyleFromConfig(config_dict) + self.assertTrue(_LooksLikePEP8Style(cfg)) + self.assertEqual(cfg['INDENT_WIDTH'], 2) + + def testDefaultBasedOnStyleBadDict(self): + self.assertRaisesRegexp(style.StyleConfigError, 'Unknown style option', + style.CreateStyleFromConfig, + {'based_on_styl': 'pep8'}) + self.assertRaisesRegexp(style.StyleConfigError, 'not a valid', + style.CreateStyleFromConfig, + {'INDENT_WIDTH': 'FOUR'}) + + +class StyleFromCommandLine(unittest.TestCase): + + @classmethod + def setUpClass(cls): # pylint: disable=g-missing-super-call + style.SetGlobalStyle(style.CreatePEP8Style()) + + def testDefaultBasedOnStyle(self): + cfg = style.CreateStyleFromConfig( + '{based_on_style: pep8,' + ' indent_width: 2,' + ' blank_line_before_nested_class_or_def: True}') + self.assertTrue(_LooksLikePEP8Style(cfg)) + self.assertEqual(cfg['INDENT_WIDTH'], 2) + + def testDefaultBasedOnStyleNotStrict(self): + cfg = style.CreateStyleFromConfig( + '{based_on_style : pep8' + ' ,indent_width=2' + ' blank_line_before_nested_class_or_def:True}') + self.assertTrue(_LooksLikePEP8Style(cfg)) + self.assertEqual(cfg['INDENT_WIDTH'], 2) + + def testDefaultBasedOnExplicitlyUnicodeTypeString(self): + cfg = style.CreateStyleFromConfig(u'{}') + self.assertIsInstance(cfg, dict) + + def testDefaultBasedOnDetaultTypeString(self): + cfg = style.CreateStyleFromConfig('{}') + self.assertIsInstance(cfg, dict) + + def testDefaultBasedOnStyleBadString(self): + self.assertRaisesRegexp(style.StyleConfigError, 'Unknown style option', + style.CreateStyleFromConfig, + '{based_on_styl: pep8}') + self.assertRaisesRegexp(style.StyleConfigError, 'not a valid', + style.CreateStyleFromConfig, '{INDENT_WIDTH: FOUR}') + self.assertRaisesRegexp(style.StyleConfigError, 'Invalid style dict', + style.CreateStyleFromConfig, + '{based_on_style: pep8') + + +class StyleHelp(unittest.TestCase): + + def testHelpKeys(self): + settings = sorted(style.Help()) + expected = sorted(style._style) + self.assertListEqual(settings, expected) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/subtype_assigner_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/subtype_assigner_test.py new file mode 100644 index 00000000..b42b8cfa --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/subtype_assigner_test.py @@ -0,0 +1,304 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.subtype_assigner.""" + +import textwrap +import unittest + +from yapf.yapflib import format_token +from yapf.yapflib import pytree_utils + +from yapftests import yapf_test_helper + + +class SubtypeAssignerTest(yapf_test_helper.YAPFTest): + + def _CheckFormatTokenSubtypes(self, uwlines, list_of_expected): + """Check that the tokens in the UnwrappedLines have the expected subtypes. + + Args: + uwlines: list of UnwrappedLine. + list_of_expected: list of (name, subtype) pairs. Non-semantic tokens are + filtered out from the expected values. + """ + actual = [] + for uwl in uwlines: + filtered_values = [(ft.value, ft.subtypes) + for ft in uwl.tokens + if ft.name not in pytree_utils.NONSEMANTIC_TOKENS] + if filtered_values: + actual.append(filtered_values) + + self.assertEqual(list_of_expected, actual) + + def testFuncDefDefaultAssign(self): + self.maxDiff = None # pylint: disable=invalid-name + code = textwrap.dedent(r""" + def foo(a=37, *b, **c): + return -x[:42] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckFormatTokenSubtypes(uwlines, [ + [ + ('def', [format_token.Subtype.NONE]), + ('foo', {format_token.Subtype.FUNC_DEF}), + ('(', {format_token.Subtype.NONE}), + ('a', { + format_token.Subtype.NONE, + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST, + format_token.Subtype.PARAMETER_START, + }), + ('=', { + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN, + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST, + }), + ('37', { + format_token.Subtype.NONE, + format_token.Subtype.PARAMETER_STOP, + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST, + }), + (',', {format_token.Subtype.NONE}), + ('*', { + format_token.Subtype.PARAMETER_START, + format_token.Subtype.VARARGS_STAR, + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST, + }), + ('b', { + format_token.Subtype.NONE, + format_token.Subtype.PARAMETER_STOP, + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST, + }), + (',', {format_token.Subtype.NONE}), + ('**', { + format_token.Subtype.PARAMETER_START, + format_token.Subtype.KWARGS_STAR_STAR, + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST, + }), + ('c', { + format_token.Subtype.NONE, + format_token.Subtype.PARAMETER_STOP, + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST, + }), + (')', {format_token.Subtype.NONE}), + (':', [format_token.Subtype.NONE]), + ], + [ + ('return', [format_token.Subtype.NONE]), + ('-', {format_token.Subtype.UNARY_OPERATOR}), + ('x', [format_token.Subtype.NONE]), + ('[', {format_token.Subtype.SUBSCRIPT_BRACKET}), + (':', {format_token.Subtype.SUBSCRIPT_COLON}), + ('42', [format_token.Subtype.NONE]), + (']', {format_token.Subtype.SUBSCRIPT_BRACKET}), + ], + ]) + + def testFuncCallWithDefaultAssign(self): + code = textwrap.dedent(r""" + foo(x, a='hello world') + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckFormatTokenSubtypes(uwlines, [ + [ + ('foo', [format_token.Subtype.NONE]), + ('(', [format_token.Subtype.NONE]), + ('x', { + format_token.Subtype.NONE, + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST, + }), + (',', {format_token.Subtype.NONE}), + ('a', { + format_token.Subtype.NONE, + format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN_ARG_LIST, + }), + ('=', {format_token.Subtype.DEFAULT_OR_NAMED_ASSIGN}), + ("'hello world'", {format_token.Subtype.NONE}), + (')', [format_token.Subtype.NONE]), + ], + ]) + + def testSetComprehension(self): + code = textwrap.dedent("""\ + def foo(strs): + return {s.lower() for s in strs} + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckFormatTokenSubtypes(uwlines, [ + [ + ('def', [format_token.Subtype.NONE]), + ('foo', {format_token.Subtype.FUNC_DEF}), + ('(', {format_token.Subtype.NONE}), + ('strs', { + format_token.Subtype.NONE, + format_token.Subtype.PARAMETER_START, + format_token.Subtype.PARAMETER_STOP, + }), + (')', {format_token.Subtype.NONE}), + (':', [format_token.Subtype.NONE]), + ], + [ + ('return', [format_token.Subtype.NONE]), + ('{', [format_token.Subtype.NONE]), + ('s', {format_token.Subtype.COMP_EXPR}), + ('.', {format_token.Subtype.COMP_EXPR}), + ('lower', {format_token.Subtype.COMP_EXPR}), + ('(', {format_token.Subtype.COMP_EXPR}), + (')', {format_token.Subtype.COMP_EXPR}), + ('for', { + format_token.Subtype.DICT_SET_GENERATOR, + format_token.Subtype.COMP_FOR, + }), + ('s', {format_token.Subtype.COMP_FOR}), + ('in', {format_token.Subtype.COMP_FOR}), + ('strs', {format_token.Subtype.COMP_FOR}), + ('}', [format_token.Subtype.NONE]), + ], + ]) + + def testUnaryNotOperator(self): + code = textwrap.dedent("""\ + not a + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckFormatTokenSubtypes( + uwlines, [[('not', {format_token.Subtype.UNARY_OPERATOR}), + ('a', [format_token.Subtype.NONE])]]) + + def testBitwiseOperators(self): + code = textwrap.dedent("""\ + x = ((a | (b ^ 3) & c) << 3) >> 1 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckFormatTokenSubtypes(uwlines, [ + [ + ('x', [format_token.Subtype.NONE]), + ('=', {format_token.Subtype.ASSIGN_OPERATOR}), + ('(', [format_token.Subtype.NONE]), + ('(', [format_token.Subtype.NONE]), + ('a', [format_token.Subtype.NONE]), + ('|', {format_token.Subtype.BINARY_OPERATOR}), + ('(', [format_token.Subtype.NONE]), + ('b', [format_token.Subtype.NONE]), + ('^', {format_token.Subtype.BINARY_OPERATOR}), + ('3', [format_token.Subtype.NONE]), + (')', [format_token.Subtype.NONE]), + ('&', {format_token.Subtype.BINARY_OPERATOR}), + ('c', [format_token.Subtype.NONE]), + (')', [format_token.Subtype.NONE]), + ('<<', {format_token.Subtype.BINARY_OPERATOR}), + ('3', [format_token.Subtype.NONE]), + (')', [format_token.Subtype.NONE]), + ('>>', {format_token.Subtype.BINARY_OPERATOR}), + ('1', [format_token.Subtype.NONE]), + ], + ]) + + def testArithmeticOperators(self): + code = textwrap.dedent("""\ + x = ((a + (b - 3) * (1 % c) @ d) / 3) // 1 + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckFormatTokenSubtypes(uwlines, [ + [ + ('x', [format_token.Subtype.NONE]), + ('=', {format_token.Subtype.ASSIGN_OPERATOR}), + ('(', [format_token.Subtype.NONE]), + ('(', [format_token.Subtype.NONE]), + ('a', [format_token.Subtype.NONE]), + ('+', { + format_token.Subtype.BINARY_OPERATOR, + format_token.Subtype.A_EXPR_OPERATOR, + }), + ('(', [format_token.Subtype.NONE]), + ('b', [format_token.Subtype.NONE]), + ('-', { + format_token.Subtype.BINARY_OPERATOR, + format_token.Subtype.A_EXPR_OPERATOR, + format_token.Subtype.SIMPLE_EXPRESSION, + }), + ('3', [format_token.Subtype.NONE]), + (')', [format_token.Subtype.NONE]), + ('*', { + format_token.Subtype.BINARY_OPERATOR, + format_token.Subtype.M_EXPR_OPERATOR, + }), + ('(', [format_token.Subtype.NONE]), + ('1', [format_token.Subtype.NONE]), + ('%', { + format_token.Subtype.BINARY_OPERATOR, + format_token.Subtype.M_EXPR_OPERATOR, + format_token.Subtype.SIMPLE_EXPRESSION, + }), + ('c', [format_token.Subtype.NONE]), + (')', [format_token.Subtype.NONE]), + ('@', { + format_token.Subtype.BINARY_OPERATOR, + format_token.Subtype.M_EXPR_OPERATOR, + }), + ('d', [format_token.Subtype.NONE]), + (')', [format_token.Subtype.NONE]), + ('/', { + format_token.Subtype.BINARY_OPERATOR, + format_token.Subtype.M_EXPR_OPERATOR, + }), + ('3', [format_token.Subtype.NONE]), + (')', [format_token.Subtype.NONE]), + ('//', { + format_token.Subtype.BINARY_OPERATOR, + format_token.Subtype.M_EXPR_OPERATOR, + }), + ('1', [format_token.Subtype.NONE]), + ], + ]) + + def testSubscriptColon(self): + code = textwrap.dedent("""\ + x[0:42:1] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckFormatTokenSubtypes(uwlines, [ + [ + ('x', [format_token.Subtype.NONE]), + ('[', {format_token.Subtype.SUBSCRIPT_BRACKET}), + ('0', [format_token.Subtype.NONE]), + (':', {format_token.Subtype.SUBSCRIPT_COLON}), + ('42', [format_token.Subtype.NONE]), + (':', {format_token.Subtype.SUBSCRIPT_COLON}), + ('1', [format_token.Subtype.NONE]), + (']', {format_token.Subtype.SUBSCRIPT_BRACKET}), + ], + ]) + + def testFunctionCallWithStarExpression(self): + code = textwrap.dedent("""\ + [a, *b] + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + self._CheckFormatTokenSubtypes(uwlines, [ + [ + ('[', [format_token.Subtype.NONE]), + ('a', [format_token.Subtype.NONE]), + (',', [format_token.Subtype.NONE]), + ('*', { + format_token.Subtype.UNARY_OPERATOR, + format_token.Subtype.VARARGS_STAR, + }), + ('b', [format_token.Subtype.NONE]), + (']', [format_token.Subtype.NONE]), + ], + ]) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/unwrapped_line_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/unwrapped_line_test.py new file mode 100644 index 00000000..90be1a13 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/unwrapped_line_test.py @@ -0,0 +1,96 @@ +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.unwrapped_line.""" + +import textwrap +import unittest + +from lib2to3 import pytree +from lib2to3.pgen2 import token + +from yapf.yapflib import format_token +from yapf.yapflib import split_penalty +from yapf.yapflib import unwrapped_line + +from yapftests import yapf_test_helper + + +class UnwrappedLineBasicTest(unittest.TestCase): + + def testConstruction(self): + toks = _MakeFormatTokenList([(token.DOT, '.'), (token.VBAR, '|')]) + uwl = unwrapped_line.UnwrappedLine(20, toks) + self.assertEqual(20, uwl.depth) + self.assertEqual(['DOT', 'VBAR'], [tok.name for tok in uwl.tokens]) + + def testFirstLast(self): + toks = _MakeFormatTokenList([(token.DOT, '.'), (token.LPAR, '('), + (token.VBAR, '|')]) + uwl = unwrapped_line.UnwrappedLine(20, toks) + self.assertEqual(20, uwl.depth) + self.assertEqual('DOT', uwl.first.name) + self.assertEqual('VBAR', uwl.last.name) + + def testAsCode(self): + toks = _MakeFormatTokenList([(token.DOT, '.'), (token.LPAR, '('), + (token.VBAR, '|')]) + uwl = unwrapped_line.UnwrappedLine(2, toks) + self.assertEqual(' . ( |', uwl.AsCode()) + + def testAppendToken(self): + uwl = unwrapped_line.UnwrappedLine(0) + uwl.AppendToken(_MakeFormatTokenLeaf(token.LPAR, '(')) + uwl.AppendToken(_MakeFormatTokenLeaf(token.RPAR, ')')) + self.assertEqual(['LPAR', 'RPAR'], [tok.name for tok in uwl.tokens]) + + def testAppendNode(self): + uwl = unwrapped_line.UnwrappedLine(0) + uwl.AppendNode(pytree.Leaf(token.LPAR, '(')) + uwl.AppendNode(pytree.Leaf(token.RPAR, ')')) + self.assertEqual(['LPAR', 'RPAR'], [tok.name for tok in uwl.tokens]) + + +class UnwrappedLineFormattingInformationTest(yapf_test_helper.YAPFTest): + + def testFuncDef(self): + code = textwrap.dedent(r""" + def f(a, b): + pass + """) + uwlines = yapf_test_helper.ParseAndUnwrap(code) + + f = uwlines[0].tokens[1] + self.assertFalse(f.can_break_before) + self.assertFalse(f.must_break_before) + self.assertEqual(f.split_penalty, split_penalty.UNBREAKABLE) + + lparen = uwlines[0].tokens[2] + self.assertFalse(lparen.can_break_before) + self.assertFalse(lparen.must_break_before) + self.assertEqual(lparen.split_penalty, split_penalty.UNBREAKABLE) + + +def _MakeFormatTokenLeaf(token_type, token_value): + return format_token.FormatToken(pytree.Leaf(token_type, token_value)) + + +def _MakeFormatTokenList(token_type_values): + return [ + _MakeFormatTokenLeaf(token_type, token_value) + for token_type, token_value in token_type_values + ] + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/utils.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/utils.py new file mode 100644 index 00000000..268b8c43 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/utils.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Utilities for tests.""" + +import contextlib +import io +import os +import sys +import tempfile + + +@contextlib.contextmanager +def stdout_redirector(stream): # pylint: disable=invalid-name + old_stdout = sys.stdout + sys.stdout = stream + try: + yield + finally: + sys.stdout = old_stdout + + +# NamedTemporaryFile is useless because on Windows the temporary file would be +# created with O_TEMPORARY, which would not allow the file to be opened a +# second time, even by the same process, unless the same flag is used. +# Thus we provide a simplified version ourselves. +# +# Note: returns a tuple of (io.file_obj, file_path), instead of a file_obj with +# a .name attribute +# +# Note: `buffering` is set to -1 despite documentation of NamedTemporaryFile +# says None. This is probably a problem with the python documentation. +@contextlib.contextmanager +def NamedTempFile(mode='w+b', + buffering=-1, + encoding=None, + errors=None, + newline=None, + suffix=None, + prefix=None, + dirname=None, + text=False): + """Context manager creating a new temporary file in text mode.""" + if sys.version_info < (3, 5): # covers also python 2 + if suffix is None: + suffix = '' + if prefix is None: + prefix = 'tmp' + (fd, fname) = tempfile.mkstemp( + suffix=suffix, prefix=prefix, dir=dirname, text=text) + f = io.open( + fd, + mode=mode, + buffering=buffering, + encoding=encoding, + errors=errors, + newline=newline) + yield f, fname + f.close() + os.remove(fname) + + +@contextlib.contextmanager +def TempFileContents(dirname, + contents, + encoding='utf-8', + newline='', + suffix=None): + # Note: NamedTempFile properly handles unicode encoding when using mode='w' + with NamedTempFile( + dirname=dirname, + mode='w', + encoding=encoding, + newline=newline, + suffix=suffix) as (f, fname): + f.write(contents) + f.flush() + yield fname diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/yapf_test.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/yapf_test.py new file mode 100644 index 00000000..e3e3df38 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/yapf_test.py @@ -0,0 +1,2038 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for yapf.yapf.""" + +import io +import logging +import os +import shutil +import subprocess +import sys +import tempfile +import textwrap +import unittest + +from lib2to3.pgen2 import tokenize + +from yapf.yapflib import py3compat +from yapf.yapflib import style +from yapf.yapflib import yapf_api + +from yapftests import utils +from yapftests import yapf_test_helper + +ROOT_DIR = os.path.dirname(os.path.abspath(os.path.dirname(__file__))) + +# Verification is turned off by default, but want to enable it for testing. +YAPF_BINARY = [sys.executable, '-m', 'yapf', '--verify', '--no-local-style'] + + +class FormatCodeTest(yapf_test_helper.YAPFTest): + + def _Check(self, unformatted_code, expected_formatted_code): + formatted_code, _ = yapf_api.FormatCode( + unformatted_code, style_config='yapf') + self.assertCodeEqual(expected_formatted_code, formatted_code) + + def testSimple(self): + unformatted_code = textwrap.dedent("""\ + print('foo') + """) + self._Check(unformatted_code, unformatted_code) + + def testNoEndingNewline(self): + unformatted_code = textwrap.dedent("""\ + if True: + pass""") + expected_formatted_code = textwrap.dedent("""\ + if True: + pass + """) + self._Check(unformatted_code, expected_formatted_code) + + def testPrintAfterPeriod(self): + unformatted_code = textwrap.dedent("""a.print\n""") + expected_formatted_code = textwrap.dedent("""a.print\n""") + self._Check(unformatted_code, expected_formatted_code) + + +class FormatFileTest(unittest.TestCase): + + def setUp(self): # pylint: disable=g-missing-super-call + self.test_tmpdir = tempfile.mkdtemp() + + def tearDown(self): # pylint: disable=g-missing-super-call + shutil.rmtree(self.test_tmpdir) + + def assertCodeEqual(self, expected_code, code): + if code != expected_code: + msg = 'Code format mismatch:\n' + msg += 'Expected:\n >' + msg += '\n > '.join(expected_code.splitlines()) + msg += '\nActual:\n >' + msg += '\n > '.join(code.splitlines()) + # TODO(sbc): maybe using difflib here to produce easy to read deltas? + self.fail(msg) + + def testFormatFile(self): + unformatted_code = textwrap.dedent(u"""\ + if True: + pass + """) + expected_formatted_code_pep8 = textwrap.dedent(u"""\ + if True: + pass + """) + expected_formatted_code_yapf = textwrap.dedent(u"""\ + if True: + pass + """) + with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') + self.assertCodeEqual(expected_formatted_code_pep8, formatted_code) + + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf') + self.assertCodeEqual(expected_formatted_code_yapf, formatted_code) + + def testDisableLinesPattern(self): + unformatted_code = textwrap.dedent(u"""\ + if a: b + + # yapf: disable + if f: g + + if h: i + """) + expected_formatted_code = textwrap.dedent(u"""\ + if a: b + + # yapf: disable + if f: g + + if h: i + """) + with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') + self.assertCodeEqual(expected_formatted_code, formatted_code) + + def testDisableAndReenableLinesPattern(self): + unformatted_code = textwrap.dedent(u"""\ + if a: b + + # yapf: disable + if f: g + # yapf: enable + + if h: i + """) + expected_formatted_code = textwrap.dedent(u"""\ + if a: b + + # yapf: disable + if f: g + # yapf: enable + + if h: i + """) + with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') + self.assertCodeEqual(expected_formatted_code, formatted_code) + + def testDisablePartOfMultilineComment(self): + unformatted_code = textwrap.dedent(u"""\ + if a: b + + # This is a multiline comment that disables YAPF. + # yapf: disable + if f: g + # yapf: enable + # This is a multiline comment that enables YAPF. + + if h: i + """) + + expected_formatted_code = textwrap.dedent(u"""\ + if a: b + + # This is a multiline comment that disables YAPF. + # yapf: disable + if f: g + # yapf: enable + # This is a multiline comment that enables YAPF. + + if h: i + """) + with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') + self.assertCodeEqual(expected_formatted_code, formatted_code) + + code = textwrap.dedent(u"""\ + def foo_function(): + # some comment + # yapf: disable + + foo( + bar, + baz + ) + + # yapf: enable + """) + with utils.TempFileContents(self.test_tmpdir, code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') + self.assertCodeEqual(code, formatted_code) + + def testEnabledDisabledSameComment(self): + code = textwrap.dedent(u"""\ + # yapf: disable + a(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, ddddddddddddddddddddddd, eeeeeeeeeeeeeeeeeeeeeeeeeee) + # yapf: enable + # yapf: disable + a(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, ddddddddddddddddddddddd, eeeeeeeeeeeeeeeeeeeeeeeeeee) + # yapf: enable + """) + with utils.TempFileContents(self.test_tmpdir, code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') + self.assertCodeEqual(code, formatted_code) + + def testFormatFileLinesSelection(self): + unformatted_code = textwrap.dedent(u"""\ + if a: b + + if f: g + + if h: i + """) + expected_formatted_code_lines1and2 = textwrap.dedent(u"""\ + if a: b + + if f: g + + if h: i + """) + expected_formatted_code_lines3 = textwrap.dedent(u"""\ + if a: b + + if f: g + + if h: i + """) + with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile( + filepath, style_config='pep8', lines=[(1, 2)]) + self.assertCodeEqual(expected_formatted_code_lines1and2, formatted_code) + formatted_code, _, _ = yapf_api.FormatFile( + filepath, style_config='pep8', lines=[(3, 3)]) + self.assertCodeEqual(expected_formatted_code_lines3, formatted_code) + + def testFormatFileDiff(self): + unformatted_code = textwrap.dedent(u"""\ + if True: + pass + """) + with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: + diff, _, _ = yapf_api.FormatFile(filepath, print_diff=True) + self.assertIn(u'+ pass', diff) + + def testFormatFileInPlace(self): + unformatted_code = u'True==False\n' + formatted_code = u'True == False\n' + with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: + result, _, _ = yapf_api.FormatFile(filepath, in_place=True) + self.assertEqual(result, None) + with open(filepath) as fd: + if sys.version_info[0] <= 2: + self.assertCodeEqual(formatted_code, fd.read().decode('ascii')) + else: + self.assertCodeEqual(formatted_code, fd.read()) + + self.assertRaises( + ValueError, + yapf_api.FormatFile, + filepath, + in_place=True, + print_diff=True) + + def testNoFile(self): + stream = py3compat.StringIO() + handler = logging.StreamHandler(stream) + logger = logging.getLogger('mylogger') + logger.addHandler(handler) + self.assertRaises( + IOError, yapf_api.FormatFile, 'not_a_file.py', logger=logger.error) + self.assertEqual(stream.getvalue(), + "[Errno 2] No such file or directory: 'not_a_file.py'\n") + + def testCommentsUnformatted(self): + code = textwrap.dedent(u"""\ + foo = [# A list of things + # bork + 'one', + # quark + 'two'] # yapf: disable + """) + with utils.TempFileContents(self.test_tmpdir, code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') + self.assertCodeEqual(code, formatted_code) + + def testDisabledHorizontalFormattingOnNewLine(self): + code = textwrap.dedent(u"""\ + # yapf: disable + a = [ + 1] + # yapf: enable + """) + with utils.TempFileContents(self.test_tmpdir, code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') + self.assertCodeEqual(code, formatted_code) + + def testSplittingSemicolonStatements(self): + unformatted_code = textwrap.dedent(u"""\ + def f(): + x = y + 42 ; z = n * 42 + if True: a += 1 ; b += 1; c += 1 + """) + expected_formatted_code = textwrap.dedent(u"""\ + def f(): + x = y + 42 + z = n * 42 + if True: + a += 1 + b += 1 + c += 1 + """) + with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') + self.assertCodeEqual(expected_formatted_code, formatted_code) + + def testSemicolonStatementsDisabled(self): + unformatted_code = textwrap.dedent(u"""\ + def f(): + x = y + 42 ; z = n * 42 # yapf: disable + if True: a += 1 ; b += 1; c += 1 + """) + expected_formatted_code = textwrap.dedent(u"""\ + def f(): + x = y + 42 ; z = n * 42 # yapf: disable + if True: + a += 1 + b += 1 + c += 1 + """) + with utils.TempFileContents(self.test_tmpdir, unformatted_code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') + self.assertCodeEqual(expected_formatted_code, formatted_code) + + def testDisabledSemiColonSeparatedStatements(self): + code = textwrap.dedent(u"""\ + # yapf: disable + if True: a ; b + """) + with utils.TempFileContents(self.test_tmpdir, code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='pep8') + self.assertCodeEqual(code, formatted_code) + + def testDisabledMultilineStringInDictionary(self): + code = textwrap.dedent(u"""\ + # yapf: disable + + A = [ + { + "aaaaaaaaaaaaaaaaaaa": ''' + bbbbbbbbbbb: "ccccccccccc" + dddddddddddddd: 1 + eeeeeeee: 0 + ffffffffff: "ggggggg" + ''', + }, + ] + """) + with utils.TempFileContents(self.test_tmpdir, code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf') + self.assertCodeEqual(code, formatted_code) + + def testDisabledWithPrecedingText(self): + code = textwrap.dedent(u"""\ + # TODO(fix formatting): yapf: disable + + A = [ + { + "aaaaaaaaaaaaaaaaaaa": ''' + bbbbbbbbbbb: "ccccccccccc" + dddddddddddddd: 1 + eeeeeeee: 0 + ffffffffff: "ggggggg" + ''', + }, + ] + """) + with utils.TempFileContents(self.test_tmpdir, code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf') + self.assertCodeEqual(code, formatted_code) + + def testCRLFLineEnding(self): + code = u'class _():\r\n pass\r\n' + with utils.TempFileContents(self.test_tmpdir, code) as filepath: + formatted_code, _, _ = yapf_api.FormatFile(filepath, style_config='yapf') + self.assertCodeEqual(code, formatted_code) + + +class CommandLineTest(unittest.TestCase): + """Test how calling yapf from the command line acts.""" + + @classmethod + def setUpClass(cls): # pylint: disable=g-missing-super-call + cls.test_tmpdir = tempfile.mkdtemp() + + @classmethod + def tearDownClass(cls): # pylint: disable=g-missing-super-call + shutil.rmtree(cls.test_tmpdir) + + def assertYapfReformats(self, + unformatted, + expected, + extra_options=None, + env=None): + """Check that yapf reformats the given code as expected. + + Invokes yapf in a subprocess, piping the unformatted code into its stdin. + Checks that the formatted output is as expected. + + Arguments: + unformatted: unformatted code - input to yapf + expected: expected formatted code at the output of yapf + extra_options: iterable of extra command-line options to pass to yapf + env: dict of environment variables. + """ + cmdline = YAPF_BINARY + (extra_options or []) + p = subprocess.Popen( + cmdline, + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env) + reformatted_code, stderrdata = p.communicate( + unformatted.encode('utf-8-sig')) + self.assertEqual(stderrdata, b'') + self.assertMultiLineEqual(reformatted_code.decode('utf-8'), expected) + + def testUnicodeEncodingPipedToFile(self): + unformatted_code = textwrap.dedent(u"""\ + def foo(): + print('⇒') + """) + with utils.NamedTempFile( + dirname=self.test_tmpdir, suffix='.py') as (out, _): + with utils.TempFileContents( + self.test_tmpdir, unformatted_code, suffix='.py') as filepath: + subprocess.check_call(YAPF_BINARY + ['--diff', filepath], stdout=out) + + def testInPlaceReformatting(self): + unformatted_code = textwrap.dedent(u"""\ + def foo(): + x = 37 + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): + x = 37 + """) + with utils.TempFileContents( + self.test_tmpdir, unformatted_code, suffix='.py') as filepath: + p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath]) + p.wait() + with io.open(filepath, mode='r', newline='') as fd: + reformatted_code = fd.read() + self.assertEqual(reformatted_code, expected_formatted_code) + + def testInPlaceReformattingBlank(self): + unformatted_code = u'\n\n' + expected_formatted_code = u'\n' + with utils.TempFileContents( + self.test_tmpdir, unformatted_code, suffix='.py') as filepath: + p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath]) + p.wait() + with io.open(filepath, mode='r', encoding='utf-8', newline='') as fd: + reformatted_code = fd.read() + self.assertEqual(reformatted_code, expected_formatted_code) + + def testInPlaceReformattingEmpty(self): + unformatted_code = u'' + expected_formatted_code = u'' + with utils.TempFileContents( + self.test_tmpdir, unformatted_code, suffix='.py') as filepath: + p = subprocess.Popen(YAPF_BINARY + ['--in-place', filepath]) + p.wait() + with io.open(filepath, mode='r', encoding='utf-8', newline='') as fd: + reformatted_code = fd.read() + self.assertEqual(reformatted_code, expected_formatted_code) + + def testReadFromStdin(self): + unformatted_code = textwrap.dedent("""\ + def foo(): + x = 37 + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): + x = 37 + """) + self.assertYapfReformats(unformatted_code, expected_formatted_code) + + def testReadFromStdinWithEscapedStrings(self): + unformatted_code = textwrap.dedent("""\ + s = "foo\\nbar" + """) + expected_formatted_code = textwrap.dedent("""\ + s = "foo\\nbar" + """) + self.assertYapfReformats(unformatted_code, expected_formatted_code) + + def testSetYapfStyle(self): + unformatted_code = textwrap.dedent("""\ + def foo(): # trail + x = 37 + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): # trail + x = 37 + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style=yapf']) + + def testSetCustomStyleBasedOnYapf(self): + unformatted_code = textwrap.dedent("""\ + def foo(): # trail + x = 37 + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): # trail + x = 37 + """) + style_file = textwrap.dedent(u'''\ + [style] + based_on_style = yapf + spaces_before_comment = 4 + ''') + with utils.TempFileContents(self.test_tmpdir, style_file) as stylepath: + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style={0}'.format(stylepath)]) + + def testSetCustomStyleSpacesBeforeComment(self): + unformatted_code = textwrap.dedent("""\ + a_very_long_statement_that_extends_way_beyond # Comment + short # This is a shorter statement + """) + expected_formatted_code = textwrap.dedent("""\ + a_very_long_statement_that_extends_way_beyond # Comment + short # This is a shorter statement + """) + style_file = textwrap.dedent(u'''\ + [style] + spaces_before_comment = 15, 20 + ''') + with utils.TempFileContents(self.test_tmpdir, style_file) as stylepath: + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style={0}'.format(stylepath)]) + + def testReadSingleLineCodeFromStdin(self): + unformatted_code = textwrap.dedent("""\ + if True: pass + """) + expected_formatted_code = textwrap.dedent("""\ + if True: pass + """) + self.assertYapfReformats(unformatted_code, expected_formatted_code) + + def testEncodingVerification(self): + unformatted_code = textwrap.dedent(u"""\ + '''The module docstring.''' + # -*- coding: utf-8 -*- + def f(): + x = 37 + """) + + with utils.NamedTempFile( + suffix='.py', dirname=self.test_tmpdir) as (out, _): + with utils.TempFileContents( + self.test_tmpdir, unformatted_code, suffix='.py') as filepath: + try: + subprocess.check_call(YAPF_BINARY + ['--diff', filepath], stdout=out) + except subprocess.CalledProcessError as e: + # Indicates the text changed. + self.assertEqual(e.returncode, 1) # pylint: disable=g-assert-in-except + + def testReformattingSpecificLines(self): + unformatted_code = textwrap.dedent("""\ + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + + def g(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + + def g(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + """) + # TODO(ambv): the `expected_formatted_code` here is not PEP8 compliant, + # raising "E129 visually indented line with same indent as next logical + # line" with flake8. + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '1-2']) + + def testOmitFormattingLinesBeforeDisabledFunctionComment(self): + unformatted_code = textwrap.dedent("""\ + import sys + + # Comment + def some_func(x): + x = ["badly" , "formatted","line" ] + """) + expected_formatted_code = textwrap.dedent("""\ + import sys + + # Comment + def some_func(x): + x = ["badly", "formatted", "line"] + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '5-5']) + + def testReformattingSkippingLines(self): + unformatted_code = textwrap.dedent("""\ + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + # yapf: disable + def g(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + # yapf: enable + """) + expected_formatted_code = textwrap.dedent("""\ + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + + # yapf: disable + def g(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + # yapf: enable + """) + self.assertYapfReformats(unformatted_code, expected_formatted_code) + + def testReformattingSkippingToEndOfFile(self): + unformatted_code = textwrap.dedent("""\ + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + # yapf: disable + def g(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + def f(): + def e(): + while (xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) == + 'bbbbbbb'): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + + # yapf: disable + def g(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + def f(): + def e(): + while (xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxxxxxxxxxxx(yyyyyyyyyyyyy[zzzzz].aaaaaaaa[0]) == + 'bbbbbbb'): + pass + """) + self.assertYapfReformats(unformatted_code, expected_formatted_code) + + def testReformattingSkippingSingleLine(self): + unformatted_code = textwrap.dedent("""\ + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + def g(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): # yapf: disable + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + + def g(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): # yapf: disable + pass + """) + self.assertYapfReformats(unformatted_code, expected_formatted_code) + + def testDisableWholeDataStructure(self): + unformatted_code = textwrap.dedent("""\ + A = set([ + 'hello', + 'world', + ]) # yapf: disable + """) + expected_formatted_code = textwrap.dedent("""\ + A = set([ + 'hello', + 'world', + ]) # yapf: disable + """) + self.assertYapfReformats(unformatted_code, expected_formatted_code) + + def testDisableButAdjustIndentations(self): + unformatted_code = textwrap.dedent("""\ + class SplitPenaltyTest(unittest.TestCase): + def testUnbreakable(self): + self._CheckPenalties(tree, [ + ]) # yapf: disable + """) + expected_formatted_code = textwrap.dedent("""\ + class SplitPenaltyTest(unittest.TestCase): + def testUnbreakable(self): + self._CheckPenalties(tree, [ + ]) # yapf: disable + """) + self.assertYapfReformats(unformatted_code, expected_formatted_code) + + def testRetainingHorizontalWhitespace(self): + unformatted_code = textwrap.dedent("""\ + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + def g(): + if (xxxxxxxxxxxx.yyyyyyyy (zzzzzzzzzzzzz [0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): # yapf: disable + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + + def g(): + if (xxxxxxxxxxxx.yyyyyyyy (zzzzzzzzzzzzz [0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): # yapf: disable + pass + """) + self.assertYapfReformats(unformatted_code, expected_formatted_code) + + def testRetainingVerticalWhitespace(self): + unformatted_code = textwrap.dedent("""\ + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + def g(): + + + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def h(): + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and + xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + pass + + def g(): + + + if (xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0]) == 'aaaaaaaaaaa' and xxxxxxxxxxxx.yyyyyyyy(zzzzzzzzzzzzz[0].mmmmmmmm[0]) == 'bbbbbbb'): + + pass + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '1-2']) + + unformatted_code = textwrap.dedent("""\ + + + if a: b + + + if c: + to_much + indent + + same + + + + #comment + + # trailing whitespace + """) + expected_formatted_code = textwrap.dedent("""\ + if a: b + + + if c: + to_much + indent + + same + + + + #comment + + # trailing whitespace + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '3-3', '--lines', '13-13']) + + unformatted_code = textwrap.dedent("""\ + ''' + docstring + + ''' + + import blah + """) + + self.assertYapfReformats( + unformatted_code, unformatted_code, extra_options=['--lines', '2-2']) + + def testVerticalSpacingWithCommentWithContinuationMarkers(self): + unformatted_code = """\ +# \\ +# \\ +# \\ + +x = { +} +""" + expected_formatted_code = """\ +# \\ +# \\ +# \\ + +x = { +} +""" + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '1-1']) + + def testRetainingSemicolonsWhenSpecifyingLines(self): + unformatted_code = textwrap.dedent("""\ + a = line_to_format + def f(): + x = y + 42; z = n * 42 + if True: a += 1 ; b += 1 ; c += 1 + """) + expected_formatted_code = textwrap.dedent("""\ + a = line_to_format + + + def f(): + x = y + 42; z = n * 42 + if True: a += 1 ; b += 1 ; c += 1 + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '1-1']) + + def testDisabledMultilineStrings(self): + unformatted_code = textwrap.dedent('''\ + foo=42 + def f(): + email_text += """This is a really long docstring that goes over the column limit and is multi-line.

+ Czar: """+despot["Nicholas"]+"""
+ Minion: """+serf["Dmitri"]+"""
+ Residence: """+palace["Winter"]+"""
+ + """ + ''') + expected_formatted_code = textwrap.dedent('''\ + foo = 42 + + + def f(): + email_text += """This is a really long docstring that goes over the column limit and is multi-line.

+ Czar: """+despot["Nicholas"]+"""
+ Minion: """+serf["Dmitri"]+"""
+ Residence: """+palace["Winter"]+"""
+ + """ + ''') + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '1-1']) + + def testDisableWhenSpecifyingLines(self): + unformatted_code = textwrap.dedent("""\ + # yapf: disable + A = set([ + 'hello', + 'world', + ]) + # yapf: enable + B = set([ + 'hello', + 'world', + ]) # yapf: disable + """) + expected_formatted_code = textwrap.dedent("""\ + # yapf: disable + A = set([ + 'hello', + 'world', + ]) + # yapf: enable + B = set([ + 'hello', + 'world', + ]) # yapf: disable + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '1-10']) + + def testDisableFormattingInDataLiteral(self): + unformatted_code = textwrap.dedent("""\ + def horrible(): + oh_god() + why_would_you() + [ + 'do', + + 'that', + ] + + def still_horrible(): + oh_god() + why_would_you() + [ + 'do', + + 'that' + ] + """) + expected_formatted_code = textwrap.dedent("""\ + def horrible(): + oh_god() + why_would_you() + [ + 'do', + + 'that', + ] + + def still_horrible(): + oh_god() + why_would_you() + ['do', 'that'] + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '14-15']) + + def testRetainVerticalFormattingBetweenDisabledAndEnabledLines(self): + unformatted_code = textwrap.dedent("""\ + class A(object): + def aaaaaaaaaaaaa(self): + c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10) + self.assertEqual( + ('ddddddddddddddddddddddddd', + 'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % + c.ffffffffffff), + gggggggggggg.hhhhhhhhh(c, c.ffffffffffff)) + iiiii = jjjjjjjjjjjjjj.iiiii + """) + expected_formatted_code = textwrap.dedent("""\ + class A(object): + def aaaaaaaaaaaaa(self): + c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10) + self.assertEqual(('ddddddddddddddddddddddddd', + 'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % c.ffffffffffff), + gggggggggggg.hhhhhhhhh(c, c.ffffffffffff)) + iiiii = jjjjjjjjjjjjjj.iiiii + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '4-7']) + + def testRetainVerticalFormattingBetweenDisabledLines(self): + unformatted_code = textwrap.dedent("""\ + class A(object): + def aaaaaaaaaaaaa(self): + pass + + + def bbbbbbbbbbbbb(self): # 5 + pass + """) + expected_formatted_code = textwrap.dedent("""\ + class A(object): + def aaaaaaaaaaaaa(self): + pass + + def bbbbbbbbbbbbb(self): # 5 + pass + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '4-4']) + + def testFormatLinesSpecifiedInMiddleOfExpression(self): + unformatted_code = textwrap.dedent("""\ + class A(object): + def aaaaaaaaaaaaa(self): + c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10) + self.assertEqual( + ('ddddddddddddddddddddddddd', + 'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % + c.ffffffffffff), + gggggggggggg.hhhhhhhhh(c, c.ffffffffffff)) + iiiii = jjjjjjjjjjjjjj.iiiii + """) + expected_formatted_code = textwrap.dedent("""\ + class A(object): + def aaaaaaaaaaaaa(self): + c = bbbbbbbbb.ccccccccc('challenge', 0, 1, 10) + self.assertEqual(('ddddddddddddddddddddddddd', + 'eeeeeeeeeeeeeeeeeeeeeeeee.%s' % c.ffffffffffff), + gggggggggggg.hhhhhhhhh(c, c.ffffffffffff)) + iiiii = jjjjjjjjjjjjjj.iiiii + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '5-6']) + + def testCommentFollowingMultilineString(self): + unformatted_code = textwrap.dedent("""\ + def foo(): + '''First line. + Second line. + ''' # comment + x = '''hello world''' # second comment + return 42 # another comment + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): + '''First line. + Second line. + ''' # comment + x = '''hello world''' # second comment + return 42 # another comment + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '1-1']) + + def testDedentClosingBracket(self): + # no line-break on the first argument, not dedenting closing brackets + unformatted_code = textwrap.dedent("""\ + def overly_long_function_name(first_argument_on_the_same_line, + second_argument_makes_the_line_too_long): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def overly_long_function_name(first_argument_on_the_same_line, + second_argument_makes_the_line_too_long): + pass + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style=pep8']) + + # TODO(ambv): currently the following produces the closing bracket on a new + # line but indented to the opening bracket which is the worst of both + # worlds. Expected behaviour would be to format as --style=pep8 does in + # this case. + # self.assertYapfReformats(unformatted_code, expected_formatted_code, + # extra_options=['--style=facebook']) + + # line-break before the first argument, dedenting closing brackets if set + unformatted_code = textwrap.dedent("""\ + def overly_long_function_name( + first_argument_on_the_same_line, + second_argument_makes_the_line_too_long): + pass + """) + # expected_formatted_pep8_code = textwrap.dedent("""\ + # def overly_long_function_name( + # first_argument_on_the_same_line, + # second_argument_makes_the_line_too_long): + # pass + # """) + expected_formatted_fb_code = textwrap.dedent("""\ + def overly_long_function_name( + first_argument_on_the_same_line, second_argument_makes_the_line_too_long + ): + pass + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_fb_code, + extra_options=['--style=facebook']) + # TODO(ambv): currently the following produces code that is not PEP8 + # compliant, raising "E125 continuation line with same indent as next + # logical line" with flake8. Expected behaviour for PEP8 would be to use + # double-indentation here. + # self.assertYapfReformats(unformatted_code, expected_formatted_pep8_code, + # extra_options=['--style=pep8']) + + def testCoalesceBrackets(self): + unformatted_code = textwrap.dedent("""\ + some_long_function_name_foo( + { + 'first_argument_of_the_thing': id, + 'second_argument_of_the_thing': "some thing" + } + )""") + expected_formatted_code = textwrap.dedent("""\ + some_long_function_name_foo({ + 'first_argument_of_the_thing': id, + 'second_argument_of_the_thing': "some thing" + }) + """) + with utils.NamedTempFile(dirname=self.test_tmpdir, mode='w') as (f, name): + f.write( + textwrap.dedent(u'''\ + [style] + column_limit=82 + coalesce_brackets = True + ''')) + f.flush() + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style={0}'.format(name)]) + + def testPseudoParenSpaces(self): + unformatted_code = textwrap.dedent("""\ + def foo(): + def bar(): + return {msg_id: author for author, msg_id in reader} + """) + expected_formatted_code = textwrap.dedent("""\ + def foo(): + + def bar(): + return {msg_id: author for author, msg_id in reader} + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '1-1', '--style', 'yapf']) + + def testMultilineCommentFormattingDisabled(self): + unformatted_code = textwrap.dedent("""\ + # This is a comment + FOO = { + aaaaaaaa.ZZZ: [ + bbbbbbbbbb.Pop(), + # Multiline comment. + # Line two. + bbbbbbbbbb.Pop(), + ], + 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': + ('yyyyy', zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz), + '#': lambda x: x # do nothing + } + """) + expected_formatted_code = textwrap.dedent("""\ + # This is a comment + FOO = { + aaaaaaaa.ZZZ: [ + bbbbbbbbbb.Pop(), + # Multiline comment. + # Line two. + bbbbbbbbbb.Pop(), + ], + 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': + ('yyyyy', zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz), + '#': lambda x: x # do nothing + } + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '1-1', '--style', 'yapf']) + + def testTrailingCommentsWithDisabledFormatting(self): + unformatted_code = textwrap.dedent("""\ + import os + + SCOPES = [ + 'hello world' # This is a comment. + ] + """) + expected_formatted_code = textwrap.dedent("""\ + import os + + SCOPES = [ + 'hello world' # This is a comment. + ] + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '1-1', '--style', 'yapf']) + + def testUseTabs(self): + unformatted_code = """\ +def foo_function(): + if True: + pass +""" + expected_formatted_code = """\ +def foo_function(): + if True: + pass +""" + style_contents = u"""\ +[style] +based_on_style = yapf +USE_TABS = true +INDENT_WIDTH=1 +""" + with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style={0}'.format(stylepath)]) + + def testUseTabsWith(self): + unformatted_code = """\ +def f(): + return ['hello', 'world',] +""" + expected_formatted_code = """\ +def f(): + return [ + 'hello', + 'world', + ] +""" + style_contents = u"""\ +[style] +based_on_style = yapf +USE_TABS = true +INDENT_WIDTH=1 +""" + with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style={0}'.format(stylepath)]) + + def testUseTabsContinuationAlignStyleFixed(self): + unformatted_code = """\ +def foo_function(arg1, arg2, arg3): + return ['hello', 'world',] +""" + expected_formatted_code = """\ +def foo_function( + arg1, arg2, arg3): + return [ + 'hello', + 'world', + ] +""" + style_contents = u"""\ +[style] +based_on_style = yapf +USE_TABS = true +COLUMN_LIMIT=32 +INDENT_WIDTH=4 +CONTINUATION_INDENT_WIDTH=8 +CONTINUATION_ALIGN_STYLE = fixed +""" + with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style={0}'.format(stylepath)]) + + def testUseTabsContinuationAlignStyleVAlignRight(self): + unformatted_code = """\ +def foo_function(arg1, arg2, arg3): + return ['hello', 'world',] +""" + expected_formatted_code = """\ +def foo_function(arg1, arg2, + arg3): + return [ + 'hello', + 'world', + ] +""" + style_contents = u"""\ +[style] +based_on_style = yapf +USE_TABS = true +COLUMN_LIMIT=32 +INDENT_WIDTH=4 +CONTINUATION_INDENT_WIDTH=8 +CONTINUATION_ALIGN_STYLE = valign-right +""" + with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style={0}'.format(stylepath)]) + + def testUseSpacesContinuationAlignStyleFixed(self): + unformatted_code = """\ +def foo_function(arg1, arg2, arg3): + return ['hello', 'world',] +""" + expected_formatted_code = """\ +def foo_function( + arg1, arg2, arg3): + return [ + 'hello', + 'world', + ] +""" + style_contents = u"""\ +[style] +based_on_style = yapf +COLUMN_LIMIT=32 +INDENT_WIDTH=4 +CONTINUATION_INDENT_WIDTH=8 +CONTINUATION_ALIGN_STYLE = fixed +""" + with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style={0}'.format(stylepath)]) + + def testUseSpacesContinuationAlignStyleVAlignRight(self): + unformatted_code = """\ +def foo_function(arg1, arg2, arg3): + return ['hello', 'world',] +""" + expected_formatted_code = """\ +def foo_function(arg1, arg2, + arg3): + return [ + 'hello', + 'world', + ] +""" + style_contents = u"""\ +[style] +based_on_style = yapf +COLUMN_LIMIT=32 +INDENT_WIDTH=4 +CONTINUATION_INDENT_WIDTH=8 +CONTINUATION_ALIGN_STYLE = valign-right +""" + with utils.TempFileContents(self.test_tmpdir, style_contents) as stylepath: + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style={0}'.format(stylepath)]) + + def testStyleOutputRoundTrip(self): + unformatted_code = textwrap.dedent("""\ + def foo_function(): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def foo_function(): + pass + """) + + with utils.NamedTempFile(dirname=self.test_tmpdir) as (stylefile, + stylepath): + p = subprocess.Popen( + YAPF_BINARY + ['--style-help'], + stdout=stylefile, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE) + _, stderrdata = p.communicate() + self.assertEqual(stderrdata, b'') + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style={0}'.format(stylepath)]) + + def testSpacingBeforeComments(self): + unformatted_code = textwrap.dedent("""\ + A = 42 + + + # A comment + def x(): + pass + def _(): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + A = 42 + + + # A comment + def x(): + pass + def _(): + pass + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--lines', '1-2']) + + def testSpacingBeforeCommentsInDicts(self): + unformatted_code = textwrap.dedent("""\ + A=42 + + X = { + # 'Valid' statuses. + PASSED: # Passed + 'PASSED', + FAILED: # Failed + 'FAILED', + TIMED_OUT: # Timed out. + 'FAILED', + BORKED: # Broken. + 'BROKEN' + } + """) + expected_formatted_code = textwrap.dedent("""\ + A = 42 + + X = { + # 'Valid' statuses. + PASSED: # Passed + 'PASSED', + FAILED: # Failed + 'FAILED', + TIMED_OUT: # Timed out. + 'FAILED', + BORKED: # Broken. + 'BROKEN' + } + """) + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style', 'yapf', '--lines', '1-1']) + + @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6') + def testNoSpacesAroundBinaryOperators(self): + unformatted_code = """\ +a = 4-b/c@d**37 +""" + expected_formatted_code = """\ +a = 4-b / c@d**37 +""" + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=[ + '--style', + '{based_on_style: pep8, ' + 'no_spaces_around_selected_binary_operators: "@,**,-"}', + ]) + + @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6') + def testCP936Encoding(self): + unformatted_code = 'print("中文")\n' + expected_formatted_code = 'print("中文")\n' + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + env={'PYTHONIOENCODING': 'cp936'}) + + def testDisableWithLineRanges(self): + unformatted_code = """\ +# yapf: disable +a = [ + 1, + 2, + + 3 +] +""" + expected_formatted_code = """\ +# yapf: disable +a = [ + 1, + 2, + + 3 +] +""" + self.assertYapfReformats( + unformatted_code, + expected_formatted_code, + extra_options=['--style', 'yapf', '--lines', '1-100']) + + +class BadInputTest(unittest.TestCase): + """Test yapf's behaviour when passed bad input.""" + + def testBadSyntax(self): + code = ' a = 1\n' + self.assertRaises(SyntaxError, yapf_api.FormatCode, code) + + def testBadCode(self): + code = 'x = """hello\n' + self.assertRaises(tokenize.TokenError, yapf_api.FormatCode, code) + + +class DiffIndentTest(unittest.TestCase): + + @staticmethod + def _OwnStyle(): + my_style = style.CreatePEP8Style() + my_style['INDENT_WIDTH'] = 3 + my_style['CONTINUATION_INDENT_WIDTH'] = 3 + return my_style + + def _Check(self, unformatted_code, expected_formatted_code): + formatted_code, _ = yapf_api.FormatCode( + unformatted_code, style_config=style.SetGlobalStyle(self._OwnStyle())) + self.assertEqual(expected_formatted_code, formatted_code) + + def testSimple(self): + unformatted_code = textwrap.dedent("""\ + for i in range(5): + print('bar') + """) + expected_formatted_code = textwrap.dedent("""\ + for i in range(5): + print('bar') + """) + self._Check(unformatted_code, expected_formatted_code) + + +class HorizontallyAlignedTrailingCommentsTest(yapf_test_helper.YAPFTest): + + @staticmethod + def _OwnStyle(): + my_style = style.CreatePEP8Style() + my_style['SPACES_BEFORE_COMMENT'] = [ + 15, + 25, + 35, + ] + return my_style + + def _Check(self, unformatted_code, expected_formatted_code): + formatted_code, _ = yapf_api.FormatCode( + unformatted_code, style_config=style.SetGlobalStyle(self._OwnStyle())) + self.assertCodeEqual(expected_formatted_code, formatted_code) + + def testSimple(self): + unformatted_code = textwrap.dedent("""\ + foo = '1' # Aligned at first list value + + foo = '2__<15>' # Aligned at second list value + + foo = '3____________<25>' # Aligned at third list value + + foo = '4______________________<35>' # Aligned beyond list values + """) + expected_formatted_code = textwrap.dedent("""\ + foo = '1' # Aligned at first list value + + foo = '2__<15>' # Aligned at second list value + + foo = '3____________<25>' # Aligned at third list value + + foo = '4______________________<35>' # Aligned beyond list values + """) + self._Check(unformatted_code, expected_formatted_code) + + def testBlock(self): + unformatted_code = textwrap.dedent("""\ + func(1) # Line 1 + func(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 + # Line 6 + """) + expected_formatted_code = textwrap.dedent("""\ + func(1) # Line 1 + func(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 + # Line 6 + """) + self._Check(unformatted_code, expected_formatted_code) + + def testBlockWithLongLine(self): + unformatted_code = textwrap.dedent("""\ + func(1) # Line 1 + func___________________(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 + # Line 6 + """) + expected_formatted_code = textwrap.dedent("""\ + func(1) # Line 1 + func___________________(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 + # Line 6 + """) + self._Check(unformatted_code, expected_formatted_code) + + def testBlockFuncSuffix(self): + unformatted_code = textwrap.dedent("""\ + func(1) # Line 1 + func(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 + # Line 6 + + def Func(): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + func(1) # Line 1 + func(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 + # Line 6 + + + def Func(): + pass + """) + self._Check(unformatted_code, expected_formatted_code) + + def testBlockCommentSuffix(self): + unformatted_code = textwrap.dedent("""\ + func(1) # Line 1 + func(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 - SpliceComments makes this part of the previous block + # Line 6 + + # Aligned with prev comment block + """) + expected_formatted_code = textwrap.dedent("""\ + func(1) # Line 1 + func(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 - SpliceComments makes this part of the previous block + # Line 6 + + # Aligned with prev comment block + """) + self._Check(unformatted_code, expected_formatted_code) + + def testBlockIndentedFuncSuffix(self): + unformatted_code = textwrap.dedent("""\ + if True: + func(1) # Line 1 + func(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 - SpliceComments makes this a new block + # Line 6 + + # Aligned with Func + + def Func(): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + func(1) # Line 1 + func(2) # Line 2 + # Line 3 + func(3) # Line 4 + + # Line 5 - SpliceComments makes this a new block + # Line 6 + + # Aligned with Func + + + def Func(): + pass + """) + self._Check(unformatted_code, expected_formatted_code) + + def testBlockIndentedCommentSuffix(self): + unformatted_code = textwrap.dedent("""\ + if True: + func(1) # Line 1 + func(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 + # Line 6 + + # Not aligned + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + func(1) # Line 1 + func(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 + # Line 6 + + # Not aligned + """) + self._Check(unformatted_code, expected_formatted_code) + + def testBlockMultiIndented(self): + unformatted_code = textwrap.dedent("""\ + if True: + if True: + if True: + func(1) # Line 1 + func(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 + # Line 6 + + # Not aligned + """) + expected_formatted_code = textwrap.dedent("""\ + if True: + if True: + if True: + func(1) # Line 1 + func(2) # Line 2 + # Line 3 + func(3) # Line 4 + # Line 5 + # Line 6 + + # Not aligned + """) + self._Check(unformatted_code, expected_formatted_code) + + def testArgs(self): + unformatted_code = textwrap.dedent("""\ + def MyFunc( + arg1, # Desc 1 + arg2, # Desc 2 + a_longer_var_name, # Desc 3 + arg4, + arg5, # Desc 5 + arg6, + ): + pass + """) + expected_formatted_code = textwrap.dedent("""\ + def MyFunc( + arg1, # Desc 1 + arg2, # Desc 2 + a_longer_var_name, # Desc 3 + arg4, + arg5, # Desc 5 + arg6, + ): + pass + """) + self._Check(unformatted_code, expected_formatted_code) + + def testDisableBlock(self): + unformatted_code = textwrap.dedent("""\ + a() # comment 1 + b() # comment 2 + + # yapf: disable + c() # comment 3 + d() # comment 4 + # yapf: enable + + e() # comment 5 + f() # comment 6 + """) + expected_formatted_code = textwrap.dedent("""\ + a() # comment 1 + b() # comment 2 + + # yapf: disable + c() # comment 3 + d() # comment 4 + # yapf: enable + + e() # comment 5 + f() # comment 6 + """) + self._Check(unformatted_code, expected_formatted_code) + + def testDisabledLine(self): + unformatted_code = textwrap.dedent("""\ + short # comment 1 + do_not_touch1 # yapf: disable + do_not_touch2 # yapf: disable + a_longer_statement # comment 2 + """) + expected_formatted_code = textwrap.dedent("""\ + short # comment 1 + do_not_touch1 # yapf: disable + do_not_touch2 # yapf: disable + a_longer_statement # comment 2 + """) + self._Check(unformatted_code, expected_formatted_code) + + +class _SpacesAroundDictListTupleTestImpl(unittest.TestCase): + + @staticmethod + def _OwnStyle(): + my_style = style.CreatePEP8Style() + my_style['DISABLE_ENDING_COMMA_HEURISTIC'] = True + my_style['SPLIT_ALL_COMMA_SEPARATED_VALUES'] = False + my_style['SPLIT_ARGUMENTS_WHEN_COMMA_TERMINATED'] = False + return my_style + + def _Check(self, unformatted_code, expected_formatted_code): + formatted_code, _ = yapf_api.FormatCode( + unformatted_code, style_config=style.SetGlobalStyle(self._OwnStyle())) + self.assertEqual(expected_formatted_code, formatted_code) + + def setUp(self): + self.maxDiff = None + + +class SpacesAroundDictTest(_SpacesAroundDictListTupleTestImpl): + + @classmethod + def _OwnStyle(cls): + style = super(SpacesAroundDictTest, cls)._OwnStyle() + style['SPACES_AROUND_DICT_DELIMITERS'] = True + + return style + + def testStandard(self): + unformatted_code = textwrap.dedent("""\ + {1 : 2} + {k:v for k, v in other.items()} + {k for k in [1, 2, 3]} + + # The following statements should not change + {} + {1 : 2} # yapf: disable + + # yapf: disable + {1 : 2} + # yapf: enable + + # Dict settings should not impact lists or tuples + [1, 2] + (3, 4) + """) + expected_formatted_code = textwrap.dedent("""\ + { 1: 2 } + { k: v for k, v in other.items() } + { k for k in [1, 2, 3] } + + # The following statements should not change + {} + {1 : 2} # yapf: disable + + # yapf: disable + {1 : 2} + # yapf: enable + + # Dict settings should not impact lists or tuples + [1, 2] + (3, 4) + """) + + self._Check(unformatted_code, expected_formatted_code) + + +class SpacesAroundListTest(_SpacesAroundDictListTupleTestImpl): + + @classmethod + def _OwnStyle(cls): + style = super(SpacesAroundListTest, cls)._OwnStyle() + style['SPACES_AROUND_LIST_DELIMITERS'] = True + + return style + + def testStandard(self): + unformatted_code = textwrap.dedent("""\ + [a,b,c] + [4,5,] + [6, [7, 8], 9] + [v for v in [1,2,3] if v & 1] + + # The following statements should not change + index[0] + index[a, b] + [] + [v for v in [1,2,3] if v & 1] # yapf: disable + + # yapf: disable + [a,b,c] + [4,5,] + # yapf: enable + + # List settings should not impact dicts or tuples + {a: b} + (1, 2) + """) + expected_formatted_code = textwrap.dedent("""\ + [ a, b, c ] + [ 4, 5, ] + [ 6, [ 7, 8 ], 9 ] + [ v for v in [ 1, 2, 3 ] if v & 1 ] + + # The following statements should not change + index[0] + index[a, b] + [] + [v for v in [1,2,3] if v & 1] # yapf: disable + + # yapf: disable + [a,b,c] + [4,5,] + # yapf: enable + + # List settings should not impact dicts or tuples + {a: b} + (1, 2) + """) + + self._Check(unformatted_code, expected_formatted_code) + + +class SpacesAroundTupleTest(_SpacesAroundDictListTupleTestImpl): + + @classmethod + def _OwnStyle(cls): + style = super(SpacesAroundTupleTest, cls)._OwnStyle() + style['SPACES_AROUND_TUPLE_DELIMITERS'] = True + + return style + + def testStandard(self): + unformatted_code = textwrap.dedent("""\ + (0, 1) + (2, 3) + (4, 5, 6,) + func((7, 8), 9) + + # The following statements should not change + func(1, 2) + (this_func or that_func)(3, 4) + if (True and False): pass + () + + (0, 1) # yapf: disable + + # yapf: disable + (0, 1) + (2, 3) + # yapf: enable + + # Tuple settings should not impact dicts or lists + {a: b} + [3, 4] + """) + expected_formatted_code = textwrap.dedent("""\ + ( 0, 1 ) + ( 2, 3 ) + ( 4, 5, 6, ) + func(( 7, 8 ), 9) + + # The following statements should not change + func(1, 2) + (this_func or that_func)(3, 4) + if (True and False): pass + () + + (0, 1) # yapf: disable + + # yapf: disable + (0, 1) + (2, 3) + # yapf: enable + + # Tuple settings should not impact dicts or lists + {a: b} + [3, 4] + """) + + self._Check(unformatted_code, expected_formatted_code) + + +if __name__ == '__main__': + unittest.main() diff --git a/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/yapf_test_helper.py b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/yapf_test_helper.py new file mode 100644 index 00000000..1f21b363 --- /dev/null +++ b/IKEA_scraper/.venv/lib/python3.9/site-packages/yapftests/yapf_test_helper.py @@ -0,0 +1,89 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Support module for tests for yapf.""" + +import difflib +import sys +import unittest + +from yapf.yapflib import blank_line_calculator +from yapf.yapflib import comment_splicer +from yapf.yapflib import continuation_splicer +from yapf.yapflib import identify_container +from yapf.yapflib import pytree_unwrapper +from yapf.yapflib import pytree_utils +from yapf.yapflib import pytree_visitor +from yapf.yapflib import split_penalty +from yapf.yapflib import style +from yapf.yapflib import subtype_assigner + + +class YAPFTest(unittest.TestCase): + + def assertCodeEqual(self, expected_code, code): + if code != expected_code: + msg = ['Code format mismatch:', 'Expected:'] + linelen = style.Get('COLUMN_LIMIT') + for l in expected_code.splitlines(): + if len(l) > linelen: + msg.append('!> %s' % l) + else: + msg.append(' > %s' % l) + msg.append('Actual:') + for l in code.splitlines(): + if len(l) > linelen: + msg.append('!> %s' % l) + else: + msg.append(' > %s' % l) + msg.append('Diff:') + msg.extend( + difflib.unified_diff( + code.splitlines(), + expected_code.splitlines(), + fromfile='actual', + tofile='expected', + lineterm='')) + self.fail('\n'.join(msg)) + + +def ParseAndUnwrap(code, dumptree=False): + """Produces unwrapped lines from the given code. + + Parses the code into a tree, performs comment splicing and runs the + unwrapper. + + Arguments: + code: code to parse as a string + dumptree: if True, the parsed pytree (after comment splicing) is dumped + to stderr. Useful for debugging. + + Returns: + List of unwrapped lines. + """ + tree = pytree_utils.ParseCodeToTree(code) + comment_splicer.SpliceComments(tree) + continuation_splicer.SpliceContinuations(tree) + subtype_assigner.AssignSubtypes(tree) + identify_container.IdentifyContainers(tree) + split_penalty.ComputeSplitPenalties(tree) + blank_line_calculator.CalculateBlankLines(tree) + + if dumptree: + pytree_visitor.DumpPyTree(tree, target_stream=sys.stderr) + + uwlines = pytree_unwrapper.UnwrapPyTree(tree) + for uwl in uwlines: + uwl.CalculateFormattingInformation() + + return uwlines diff --git a/IKEA_scraper/__pycache__/ikea.cpython-39.pyc b/IKEA_scraper/__pycache__/ikea.cpython-39.pyc index ca0c603954a888b5194b9930524fa08ab37d6cfe..b31cec4bb0c5d4ccbfb013778a8d80a4ac0d332b 100644 GIT binary patch delta 289 zcmcbk@mYf}k(ZZ?0SFrO=Ox}3+Q?_gtYE93k)NBYpIww$T#}!bT2!p>lAm0fo0?Zr ztY1)Bk})}!S%Z;#a~pFRBO~ABzbt-?2Ah3Yl^JlWqb=js>drzPqp7Ud>qBxV8~2I6kk zxW!dc7N3-wmz8oDyAxH}Y9Biy7j>U$&>rMMJjmZj