Repository: frictionlessdata/frictionless-py

Issue:
CLI: frictionless describe fails on --dialect (for --type package)
```
$ frictionless describe --dialect '{"delimiter": ";"}' --type package country-2.csv 
Package.__init__() got an unexpected keyword argument 'dialect'
```
## missing CLI option to describe a package for a directory of CSV files with non-default delimiter
CLI allows to infer schema and resource for a CSV using non-default delimiter such as ";"

However, for package, CLI shows `--dialect` option in help, but using it ends with error message which looks like internal error.

My use case is: having a directory full of CSV files with ";" as a delimiter I would like to describe the whole package using CLI.

Discussion:
shashigharti: Thank you @roll!  It is ready for the review.

Patch:
diff --git a/frictionless/package/package.py b/frictionless/package/package.py
index f88d7d30..624faab3 100644
--- a/frictionless/package/package.py
+++ b/frictionless/package/package.py
@@ -119,6 +119,9 @@ class Package(Metadata):
         hashing? (str): a hashing algorithm for resources
             It defaults to 'md5'.
 
+        dialect? (dict|Dialect): Table dialect.
+            For more information, please check the Dialect documentation.
+
     Raises:
         FrictionlessException: raise any error that occurs during the process
     """
@@ -155,6 +158,7 @@ class Package(Metadata):
         onerror="ignore",
         trusted=False,
         hashing=None,
+        dialect=None,
     ):
 
         # Handle source
@@ -198,6 +202,7 @@ class Package(Metadata):
         self.setinitial("created", created)
         self.__basepath = basepath or helpers.parse_basepath(descriptor)
         self.__detector = detector or Detector()
+        self.__dialect = dialect
         self.__onerror = onerror
         self.__trusted = trusted
         self.__hashing = hashing
@@ -713,6 +718,7 @@ class Package(Metadata):
                         resource = {"name": f"resource{index+1}"}
                     resource = Resource(
                         resource,
+                        dialect=self.__dialect,
                         basepath=self.__basepath,
                         detector=self.__detector,
                         hashing=self.__hashing,


Test patch:
diff --git a/tests/actions/describe/test_package.py b/tests/actions/describe/test_package.py
index ee0313c4..ca0cbf8d 100644
--- a/tests/actions/describe/test_package.py
+++ b/tests/actions/describe/test_package.py
@@ -128,3 +128,51 @@ def test_describe_package_expand():
     package = describe("data/chunk*.csv", expand=True)
     assert package.get_resource("chunk1").layout.header is True
     assert package.get_resource("chunk1").schema.missing_values == [""]
+
+
+def test_describe_package_with_dialect_1126():
+    package = describe("data/country-2.csv", dialect={"delimiter": ";"}, type="package")
+    assert package.get_resource("country-2")["schema"] == {
+        "fields": [
+            {"type": "integer", "name": "id"},
+            {"type": "integer", "name": "neighbor_id"},
+            {"type": "string", "name": "name"},
+            {"type": "integer", "name": "population"},
+        ]
+    }
+
+
+def test_describe_package_with_dialect_path_1126():
+    package = describe("data/country-2.csv", dialect="data/dialect.json", type="package")
+    assert package.get_resource("country-2")["schema"] == {
+        "fields": [
+            {"type": "integer", "name": "id"},
+            {"type": "integer", "name": "neighbor_id"},
+            {"type": "string", "name": "name"},
+            {"type": "integer", "name": "population"},
+        ]
+    }
+
+
+def test_describe_package_with_incorrect_dialect_1126():
+    package = describe("data/country-2.csv", dialect={"delimiter": ","}, type="package")
+    assert package.get_resource("country-2")["schema"] == {
+        "fields": [{"type": "string", "name": "# Author: the scientist"}]
+    }
+
+
+def test_describe_package_with_glob_having_one_incorrect_dialect_1126():
+    package = describe("data/country-*.csv", dialect={"delimiter": ","}, type="package")
+    resource_1 = package.get_resource("country-1")
+    resource_2 = package.get_resource("country-2")
+    assert resource_1["schema"] == {
+        "fields": [
+            {"type": "integer", "name": "id"},
+            {"type": "integer", "name": "neighbor_id"},
+            {"type": "string", "name": "name"},
+            {"type": "integer", "name": "population"},
+        ]
+    }
+    assert resource_2["schema"] == {
+        "fields": [{"type": "string", "name": "# Author: the scientist"}]
+    }
diff --git a/tests/package/describe/test_general.py b/tests/package/describe/test_general.py
index c2602201..07a89192 100644
--- a/tests/package/describe/test_general.py
+++ b/tests/package/describe/test_general.py
@@ -128,3 +128,51 @@ def test_describe_package_expand():
     package = Package.describe("data/chunk*.csv", expand=True)
     assert package.get_resource("chunk1").layout.header is True
     assert package.get_resource("chunk1").schema.missing_values == [""]
+
+
+def test_describe_package_with_dialect_1126():
+    package = Package.describe("data/country-2.csv", dialect={"delimiter": ";"})
+    assert package.get_resource("country-2")["schema"] == {
+        "fields": [
+            {"type": "integer", "name": "id"},
+            {"type": "integer", "name": "neighbor_id"},
+            {"type": "string", "name": "name"},
+            {"type": "integer", "name": "population"},
+        ]
+    }
+
+
+def test_describe_package_with_dialect_path_1126():
+    package = Package.describe("data/country-2.csv", dialect="data/dialect.json")
+    assert package.get_resource("country-2")["schema"] == {
+        "fields": [
+            {"type": "integer", "name": "id"},
+            {"type": "integer", "name": "neighbor_id"},
+            {"type": "string", "name": "name"},
+            {"type": "integer", "name": "population"},
+        ]
+    }
+
+
+def test_describe_package_with_incorrect_dialect_1126():
+    package = Package.describe("data/country-2.csv", dialect={"delimiter": ","})
+    assert package.get_resource("country-2")["schema"] == {
+        "fields": [{"type": "string", "name": "# Author: the scientist"}]
+    }
+
+
+def test_describe_package_with_glob_having_one_incorrect_dialect_1126():
+    package = Package.describe("data/country-*.csv", dialect={"delimiter": ","})
+    resource_1 = package.get_resource("country-1")
+    resource_2 = package.get_resource("country-2")
+    assert resource_1["schema"] == {
+        "fields": [
+            {"type": "integer", "name": "id"},
+            {"type": "integer", "name": "neighbor_id"},
+            {"type": "string", "name": "name"},
+            {"type": "integer", "name": "population"},
+        ]
+    }
+    assert resource_2["schema"] == {
+        "fields": [{"type": "string", "name": "# Author: the scientist"}]
+    }
diff --git a/tests/program/test_describe.py b/tests/program/test_describe.py
index fc71384e..871d94e1 100644
--- a/tests/program/test_describe.py
+++ b/tests/program/test_describe.py
@@ -171,3 +171,69 @@ def test_program_describe_basepath():
     result = runner.invoke(program, "describe --basepath data *-3.csv")
     assert result.exit_code == 0
     assert yaml.safe_load(result.stdout) == describe("*-3.csv", basepath="data")
+
+
+def test_program_describe_package_with_dialect_1126():
+    result = runner.invoke(
+        program,
+        'describe data/country-2.csv --json --dialect \'{"delimiter": ";"}\' --type package',
+    )
+    assert result.exit_code == 0
+    output = json.loads(result.stdout)
+    assert output["resources"][0]["schema"] == {
+        "fields": [
+            {"type": "integer", "name": "id"},
+            {"type": "integer", "name": "neighbor_id"},
+            {"type": "string", "name": "name"},
+            {"type": "integer", "name": "population"},
+        ]
+    }
+
+
+def test_program_describe_package_with_dialect_path_1126():
+    result = runner.invoke(
+        program,
+        "describe data/country-2.csv --json --dialect data/dialect.json --type package",
+    )
+    assert result.exit_code == 0
+    output = json.loads(result.stdout)
+    assert output["resources"][0]["schema"] == {
+        "fields": [
+            {"type": "integer", "name": "id"},
+            {"type": "integer", "name": "neighbor_id"},
+            {"type": "string", "name": "name"},
+            {"type": "integer", "name": "population"},
+        ]
+    }
+
+
+def test_program_describe_package_with_incorrect_dialect_1126():
+    result = runner.invoke(
+        program,
+        'describe data/country-2.csv --json --dialect \'{"delimiter": ","}\' --type package',
+    )
+    assert result.exit_code == 0
+    output = json.loads(result.stdout)
+    assert output["resources"][0]["schema"] == {
+        "fields": [{"type": "string", "name": "# Author: the scientist"}]
+    }
+
+
+def test_program_describe_package_with_glob_having_one_incorrect_dialect_1126():
+    result = runner.invoke(
+        program,
+        'describe data/country-*.csv --json --dialect \'{"delimiter": ","}\' --type package',
+    )
+    assert result.exit_code == 0
+    output = json.loads(result.stdout)
+    assert output["resources"][0]["schema"] == {
+        "fields": [
+            {"type": "integer", "name": "id"},
+            {"type": "integer", "name": "neighbor_id"},
+            {"type": "string", "name": "name"},
+            {"type": "integer", "name": "population"},
+        ]
+    }
+    assert output["resources"][1]["schema"] == {
+        "fields": [{"type": "string", "name": "# Author: the scientist"}]
+    }