|
25 | 25 | # Module settings |
26 | 26 | VERBOSE = True |
27 | 27 |
|
| 28 | +# Test config (for the Doctest runner and test_shapefile.py) |
| 29 | +REPLACE_REMOTE_URLS_WITH_LOCALHOST = ( |
| 30 | + os.getenv("REPLACE_REMOTE_URLS_WITH_LOCALHOST", "").lower() == "yes" |
| 31 | +) |
| 32 | + |
28 | 33 | # Constants for shape types |
29 | 34 | NULL = 0 |
30 | 35 | POINT = 1 |
@@ -2794,41 +2799,113 @@ def _get_doctests(): |
2794 | 2799 | return tests |
2795 | 2800 |
|
2796 | 2801 |
|
2797 | | -def _get_no_network_doctests(examples): |
| 2802 | +def _filter_network_doctests(examples, include_network=False, include_non_network=True): |
2798 | 2803 | globals_from_network_doctests = set() |
2799 | | - for example in examples: |
| 2804 | + |
| 2805 | + if not (include_network or include_non_network): |
| 2806 | + return |
| 2807 | + |
| 2808 | + examples_it = iter(examples) |
| 2809 | + |
| 2810 | + yield next(examples_it) |
| 2811 | + |
| 2812 | + for example in examples_it: |
| 2813 | + # Track variables in doctest shell sessions defined from commands |
| 2814 | + # that poll remote URLs, to skip subsequent commands until all |
| 2815 | + # such dependent variables are reassigned. |
| 2816 | + |
2800 | 2817 | if 'sf = shapefile.Reader("https://' in example.source: |
2801 | 2818 | globals_from_network_doctests.add("sf") |
| 2819 | + if include_network: |
| 2820 | + yield example |
2802 | 2821 | continue |
| 2822 | + |
2803 | 2823 | lhs = example.source.partition("=")[0] |
2804 | 2824 |
|
2805 | 2825 | for target in lhs.split(","): |
2806 | 2826 | target = target.strip() |
2807 | 2827 | if target in globals_from_network_doctests: |
2808 | 2828 | globals_from_network_doctests.remove(target) |
2809 | 2829 |
|
| 2830 | + # Non-network tests dependent on the network tests. |
2810 | 2831 | if globals_from_network_doctests: |
| 2832 | + if include_network: |
| 2833 | + yield example |
| 2834 | + continue |
| 2835 | + |
| 2836 | + if not include_non_network: |
2811 | 2837 | continue |
2812 | 2838 |
|
2813 | 2839 | yield example |
2814 | 2840 |
|
2815 | 2841 |
|
2816 | | -def _test(verbosity=0): |
| 2842 | +def _replace_remote_url( |
| 2843 | + old_url, |
| 2844 | + # Default port of Python http.server and Python 2's SimpleHttpServer |
| 2845 | + port=8000, |
| 2846 | + scheme="http", |
| 2847 | + netloc="localhost", |
| 2848 | + path=None, |
| 2849 | + params="", |
| 2850 | + query="", |
| 2851 | + fragment="", |
| 2852 | +): |
| 2853 | + old_parsed = urlparse(old_url) |
| 2854 | + |
| 2855 | + # Strip subpaths, so an artefacts |
| 2856 | + # repo or file tree can be simpler and flat |
| 2857 | + if path is None: |
| 2858 | + path = old_parsed.path.rpartition("/")[2] |
| 2859 | + |
| 2860 | + if port not in (None, ""): |
| 2861 | + netloc = "%s:%s" % (netloc, port) |
| 2862 | + |
| 2863 | + new_parsed = old_parsed._replace( |
| 2864 | + scheme=scheme, |
| 2865 | + netloc=netloc, |
| 2866 | + path=path, |
| 2867 | + params=params, |
| 2868 | + query=query, |
| 2869 | + fragment=fragment, |
| 2870 | + ) |
| 2871 | + |
| 2872 | + new_url = urlunparse(new_parsed) if PYTHON3 else urlunparse(list(new_parsed)) |
| 2873 | + return new_url |
| 2874 | + |
| 2875 | + |
| 2876 | +def _test(args=sys.argv[1:], verbosity=0): |
2817 | 2877 | if verbosity == 0: |
2818 | 2878 | print("Getting doctests...") |
2819 | | - tests = _get_doctests() |
2820 | | - |
2821 | | - if len(sys.argv) >= 3 and sys.argv[1:3] == ["-m", "not network"]: |
2822 | | - if verbosity == 0: |
2823 | | - print("Removing doctests requiring internet access...") |
2824 | | - tests.examples = list(_get_no_network_doctests(tests.examples)) |
2825 | 2879 |
|
2826 | 2880 | import doctest |
| 2881 | + import re |
2827 | 2882 |
|
2828 | 2883 | doctest.NORMALIZE_WHITESPACE = 1 |
2829 | 2884 |
|
2830 | | - # ignore py2-3 unicode differences |
2831 | | - import re |
| 2885 | + tests = _get_doctests() |
| 2886 | + |
| 2887 | + if len(args) >= 2 and args[0] == "-m": |
| 2888 | + if verbosity == 0: |
| 2889 | + print("Filtering doctests...") |
| 2890 | + tests.examples = list( |
| 2891 | + _filter_network_doctests( |
| 2892 | + tests.examples, |
| 2893 | + include_network=args[1] == "network", |
| 2894 | + include_non_network=args[1] == "not network", |
| 2895 | + ) |
| 2896 | + ) |
| 2897 | + |
| 2898 | + if REPLACE_REMOTE_URLS_WITH_LOCALHOST: |
| 2899 | + if verbosity == 0: |
| 2900 | + print("Replacing remote urls with http://localhost in doctests...") |
| 2901 | + |
| 2902 | + for example in tests.examples: |
| 2903 | + match_url_str_literal = re.search(r'"(https://.*)"', example.source) |
| 2904 | + if not match_url_str_literal: |
| 2905 | + continue |
| 2906 | + old_url = match_url_str_literal.group(1) |
| 2907 | + new_url = _replace_remote_url(old_url) |
| 2908 | + example.source = example.source.replace(old_url, new_url) |
2832 | 2909 |
|
2833 | 2910 | class Py23DocChecker(doctest.OutputChecker): |
2834 | 2911 | def check_output(self, want, got, optionflags): |
|
0 commit comments